template <class T> struct KindToKindId {
static const NodeKindId Id = NKI_None;
};
+ template <class T>
+ struct KindToKindId<const T> : KindToKindId<T> {};
/// \brief Per kind info.
struct KindInfo {
return BaseConverter<T>::get(NodeKind, Storage.buffer);
}
+ /// \brief Retrieve the stored node as type \c T.
+ ///
+ /// Similar to \c get(), but asserts that the type is what we are expecting.
+ template <typename T>
+ const T &getUnchecked() const {
+ return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
+ }
+
ASTNodeKind getNodeKind() const { return NodeKind; }
/// \brief Returns a pointer that identifies the stored AST node.
return getMemoizationData() < Other.getMemoizationData();
}
bool operator==(const DynTypedNode &Other) const {
- if (!NodeKind.isBaseOf(Other.NodeKind) &&
- !Other.NodeKind.isBaseOf(NodeKind))
+ // DynTypedNode::create() stores the exact kind of the node in NodeKind.
+ // If they contain the same node, their NodeKind must be the same.
+ if (!NodeKind.isSame(Other.NodeKind))
return false;
// FIXME: Implement for other types.
- if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) {
- return *get<QualType>() == *Other.get<QualType>();
- }
+ if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
+ return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
+
assert(getMemoizationData() && Other.getMemoizationData());
return getMemoizationData() == Other.getMemoizationData();
}
/// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
template <typename T, typename BaseT> struct DynCastPtrConverter {
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
- if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
- return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+ if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
+ return cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
return nullptr;
}
+ static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
+ assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
+ return *cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+ }
static DynTypedNode create(const BaseT &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNode(Node);
return *reinterpret_cast<T *const *>(Storage);
return nullptr;
}
+ static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
+ assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
+ return **reinterpret_cast<T *const *>(Storage);
+ }
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
return reinterpret_cast<const T *>(Storage);
return nullptr;
}
+ static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
+ assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
+ return *reinterpret_cast<const T *>(Storage);
+ }
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();