ast_rtti.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_EXPLORER_AST_AST_RTTI_H_
  5. #define CARBON_EXPLORER_AST_AST_RTTI_H_
  6. #include "common/enum_base.h"
  7. #include "explorer/ast/ast_kinds.h"
  8. namespace Carbon {
  9. // Assign numbers to all AST types.
  10. CARBON_DEFINE_RAW_ENUM_CLASS(AstRttiNodeKind, int) {
  11. #define DEFINE_ENUMERATOR(E) E,
  12. CARBON_AST_FOR_EACH_FINAL_CLASS(DEFINE_ENUMERATOR)
  13. #undef DEFINE_ENUMERATOR
  14. };
  15. // An enumerated type defining the kinds of AST nodes.
  16. class AstRttiNodeKind : public CARBON_ENUM_BASE(AstRttiNodeKind) {
  17. public:
  18. using IsCarbonAstRttiNodeKind = void;
  19. AstRttiNodeKind() = default;
  20. // All our other RTTI node kinds implicitly convert to this one.
  21. // TODO: We could support conversion to the base class's kind for all node
  22. // kinds if we find a reason to do so.
  23. template <typename Kind, typename = typename Kind::IsCarbonAstRttiNodeKind>
  24. /*implicit*/ AstRttiNodeKind(Kind kind)
  25. : AstRttiNodeKind(FromInt(kind.AsInt())) {}
  26. // Expose the integer value of this node. This is used to set the values of
  27. // other enumerations to match, and to implement range checks.
  28. using EnumBase::AsInt;
  29. CARBON_AST_FOR_EACH_FINAL_CLASS(CARBON_ENUM_CONSTANT_DECLARATION)
  30. };
  31. // Define the constant members for AstRttiNodeKind.
  32. #define CONSTANT_DEFINITION(E) \
  33. CARBON_ENUM_CONSTANT_DEFINITION(AstRttiNodeKind, E)
  34. CARBON_AST_FOR_EACH_FINAL_CLASS(CONSTANT_DEFINITION)
  35. #undef CONSTANT_DEFINITION
  36. // Define Kind enumerations for all base classes.
  37. #define DEFINE_KIND_ENUM(C) \
  38. CARBON_DEFINE_RAW_ENUM_CLASS(C##Kind, int) { \
  39. CARBON_AST_FOR_EACH_FINAL_CLASS_BELOW(C, DEFINE_ENUMERATOR) \
  40. }; \
  41. template <typename Derived> \
  42. class C##KindTemplate : public CARBON_ENUM_BASE_CRTP(C##Kind, Derived) { \
  43. private: \
  44. using Base = CARBON_ENUM_BASE_CRTP(C##Kind, Derived); \
  45. friend class AstRttiNodeKind; \
  46. \
  47. public: \
  48. using IsCarbonAstRttiNodeKind = void; \
  49. \
  50. C##KindTemplate() = default; \
  51. \
  52. /* This type can be explicitly converted from the generic node kind. */ \
  53. explicit C##KindTemplate(AstRttiNodeKind base_kind) \
  54. : Base(Base::FromInt(base_kind.AsInt())) {} \
  55. \
  56. CARBON_AST_FOR_EACH_FINAL_CLASS_BELOW( \
  57. C, CARBON_INLINE_ENUM_CONSTANT_DEFINITION) \
  58. }; \
  59. class C##Kind : public C##KindTemplate<C##Kind> { \
  60. using C##KindTemplate<C##Kind>::C##KindTemplate; \
  61. };
  62. #define DEFINE_ENUMERATOR(E) E = AstRttiNodeKind::E.AsInt(),
  63. CARBON_AST_FOR_EACH_ABSTRACT_CLASS(DEFINE_KIND_ENUM)
  64. #undef DEFINE_KIND_ENUM
  65. #undef DEFINE_ENUMERATOR
  66. // Define InheritsFrom functions for each abstract class.
  67. #define DEFINE_INHERITS_FROM_FUNCTION_ABSTRACT(C) \
  68. inline bool InheritsFrom##C(Carbon::AstRttiNodeKind kind) { \
  69. return CARBON_AST_FOR_EACH_FINAL_CLASS_BELOW( \
  70. C, INHERITS_FROM_CLASS_TEST) false; \
  71. }
  72. #define INHERITS_FROM_CLASS_TEST(C) kind == Carbon::AstRttiNodeKind::C ||
  73. CARBON_AST_FOR_EACH_ABSTRACT_CLASS(DEFINE_INHERITS_FROM_FUNCTION_ABSTRACT)
  74. #undef DEFINE_INHERITS_FROM_FUNCTION_ABSTRACT
  75. #undef INHERITS_FROM_CLASS_TEST
  76. // Define trivial InheritsFrom functions for each final class.
  77. #define DEFINE_INHERITS_FROM_FUNCTION_FINAL(C) \
  78. inline bool InheritsFrom##C(Carbon::AstRttiNodeKind kind) { \
  79. return kind == Carbon::AstRttiNodeKind::C; \
  80. }
  81. CARBON_AST_FOR_EACH_FINAL_CLASS(DEFINE_INHERITS_FROM_FUNCTION_FINAL)
  82. #undef DEFINE_INHERITS_FROM_FUNCTION_FINAL
  83. } // namespace Carbon
  84. #endif // CARBON_EXPLORER_AST_AST_RTTI_H_