// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Simple and efficient Run-Time Type Information // // Code available from: https://verilator.org // //************************************************************************* // // Copyright 2003-2025 by Wilson Snyder. This program is free software; you // can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // //************************************************************************* #ifndef VERILATOR_V3RTTI_H_ #define VERILATOR_V3RTTI_H_ #include "verilatedos.h" #include #include // Holds list of types as template parameter pack. // Useful in compile-time code generation. template struct VTypeList final { template constexpr VTypeList operator+(VTypeList) const { return {}; } }; // Holds one type. // Can be safely used as a return or argument type, and even instantiated, without triggering any // potential limitations or effects of the held type. template struct VTypeWrapper final { using type_t = T; }; // Implementation details of other constructs defined in this header. namespace V3RttiInternal { // Helper function for extracting first type from VTypeList. template static inline constexpr VTypeWrapper vlTypeListFront(VTypeList) { return {}; } // Overload for empty type list. Returns false. inline static constexpr bool isClassIdOfOneOf(uintptr_t id, VTypeList<>) VL_PURE { return false; } // Returns true iff `id` has the same value as `T::rttiClassId()`, where `T` is any type held by // `VTypeList` object passed as the second argument. template inline static constexpr bool isClassIdOfOneOf(uintptr_t id, VTypeList) VL_PURE { return id == Base0::rttiClassId() || isClassIdOfOneOf(id, VTypeList{}); } } // namespace V3RttiInternal // Alias for the first (frontmost) type held by type list `TL`. template using VTypeListFront = typename decltype(::V3RttiInternal::vlTypeListFront(TL{}))::type_t; // `VTypeList` holding types from type lists `TL1` followed by types from type list `TL2`. template using VJoinedTypeLists = decltype(TL1{} + TL2{}); // Common code used by VL_RTTI_COMMON_IMPL and VL_RTTI_COMMON_IMPL_BASE. #define V3RTTIINTERNAL_VL_RTTI_COMMON_IMPL(ThisClass) \ private: \ /* A type used only for implementation of the static_assert below. */ \ struct RttiUniqueTypeForThisClass {}; \ static_assert( \ std::is_same::value, \ "'ThisClass' argument (" #ThisClass ") does not match the class name"); \ \ public: \ /* Returns unique ID of the class. Useful with `isInstanceOfClassWithId()` method. */ \ static uintptr_t rttiClassId() VL_PURE { \ /* The only purpose of the following variable is to occupy an unique memory address. */ \ /* This address is used as an unique class ID. */ \ static char aStaticVariable; \ return reinterpret_cast(&aStaticVariable); \ } // Call this macro at the beginning of class definition if the class derives from a // class with VL_RTTI_IMPL or VL_RTTI_IMPL_BASE calls. #define VL_RTTI_IMPL(ThisClass, DirectBaseClass) \ V3RTTIINTERNAL_VL_RTTI_COMMON_IMPL(ThisClass) \ static_assert( \ std::is_same>::value, \ "Missing VL_RTTI_IMPL(...) in the direct base class (" #DirectBaseClass ")"); \ \ public: \ /* Type list containing this class and all classes from the inheritance chain. */ \ using RttiThisAndBaseClassesList \ = VJoinedTypeLists, \ typename DirectBaseClass::RttiThisAndBaseClassesList>; \ \ protected: \ /* Returns true iff `id` has the same value as `T::rttiClassId()`, where `T` is either this \ * class or any class from this class' inheritance chain. */ \ bool isInstanceOfClassWithId(uintptr_t id) const override VL_PURE { \ return ::V3RttiInternal::isClassIdOfOneOf(id, RttiThisAndBaseClassesList{}); \ } \ \ private: /* Revert to private visibility after this macro */ // Call this macro at the beginning of a base class to implement class type queries using // `p->isInstanceOfClassWithId(ClassName::rttiClassId())`. #define VL_RTTI_IMPL_BASE(ThisClass) \ V3RTTIINTERNAL_VL_RTTI_COMMON_IMPL(ThisClass) \ public: \ /* Type list containing this class and all classes from the inheritance chain. */ \ using RttiThisAndBaseClassesList = VTypeList; \ \ protected: \ /* Returns true iff `id` has the same value as value returned by this class' \ `rttiClassId()` method. */ \ virtual bool isInstanceOfClassWithId(uintptr_t id) const VL_PURE { \ return id == rttiClassId(); \ } \ \ private: /* Revert to private visibility after this macro */ #endif // Guard