//===--- TypeNodes.def - Swift Type AST Metaprogramming ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines macros used for macro-metaprogramming with types.
//
//===----------------------------------------------------------------------===//

/// TYPE(id, parent)
///   If the type node is not abstract, its enumerator value is
///   TypeKind::id.  The node's class name is 'id##Type', and the name of
///   its base class (in the Type hierarchy) is 'parent' (including
///   the 'Type' suffix).

/// ALWAYS_CANONICAL_TYPE(id, parent)
///   This type is always canonical.  The default behavior is TYPE(id, parent).

/// BUILTIN_TYPE(id, parent)
///   This type is a builtin type. The default behavior is
///   ALWAYS_CANONICAL_TYPE(id, parent).

/// BUILTIN_CONCRETE_TYPE(id, parent)
///   This type is a builtin type without generic parameters. The default
///   behavior is BUILTIN_TYPE(id, parent).

/// BUILTIN_GENERIC_TYPE(id, parent)
///   This type is a builtin type with generic parameters. The default
///   behavior is BUILTIN_TYPE(id, parent).

/// SUGARED_TYPE(id, parent)
///   This type is never canonical.  It provides an efficient accessor,
///   getSinglyDesugaredType(), which removes one level of sugar.  This
///   process does not necessarily converge to the canonical type, however.
///   The default behavior is TYPE(id, parent).
//
// If you add a new sugared type, be sure to test it in PrintAsClang!

/// UNCHECKED_TYPE(id, parent)
///   This type is not present in valid, type-checked programs.
///   The default behavior is TYPE(id, parent).

/// ARTIFICIAL_TYPE(id, parent)
///   This type is not part of the user-facing type system. It may be
///   used freely in SIL, and it may appear as the type of a
///   declaration in the AST (due to e.g. the application of the
///   [weak] attribute), but it cannot be written directly in normal
///   programs and it cannot be the type of an expression.
///   The default behavior is TYPE(id, parent).

/// SINGLETON_TYPE(SHORT_ID, id)
///   This type is a singleton, i.e. there is exactly one instance of
///   it, which can be found as ASTContext.The#SHORT_ID#Type.
///   This is only expanded if SINGLETON_TYPE is defined, and in this
///   case no other macros are expanded.

#ifndef ALWAYS_CANONICAL_ARTIFICIAL_TYPE
#ifdef ALWAYS_CANONICAL_TYPE
#ifdef ARTIFICIAL_TYPE
#error must define ALWAYS_CANONICAL_ARTIFICIAL_TYPE if also defining both ALWAYS_CANONICAL_TYPE and ARTIFICIAL_TYPE
#endif
#define ALWAYS_CANONICAL_ARTIFICIAL_TYPE(id, parent) ALWAYS_CANONICAL_TYPE(id, parent)
#else
#define ALWAYS_CANONICAL_ARTIFICIAL_TYPE(id, parent) ARTIFICIAL_TYPE(id, parent)
#endif
#endif

#ifndef ALWAYS_CANONICAL_TYPE
#define ALWAYS_CANONICAL_TYPE(id, parent) TYPE(id, parent)
#endif

#ifndef BUILTIN_TYPE
#define BUILTIN_TYPE(id, parent) ALWAYS_CANONICAL_TYPE(id, parent)
#endif

#ifndef BUILTIN_CONCRETE_TYPE
#define BUILTIN_CONCRETE_TYPE(id, parent) BUILTIN_TYPE(id, parent)
#endif

#ifndef BUILTIN_GENERIC_TYPE
#define BUILTIN_GENERIC_TYPE(id, parent) BUILTIN_TYPE(id, parent)
#endif

#ifndef SUGARED_TYPE
#define SUGARED_TYPE(id, parent) TYPE(id, parent)
#endif

#ifndef UNCHECKED_TYPE
#define UNCHECKED_TYPE(id, parent) TYPE(id, parent)
#endif

#ifndef ARTIFICIAL_TYPE
#define ARTIFICIAL_TYPE(id, parent) TYPE(id, parent)
#endif

/// Most metaprograms do not care about abstract types, so the default
/// is to ignore them.
#ifndef ABSTRACT_TYPE
#define ABSTRACT_TYPE(Id, Parent)
#endif

#ifndef ABSTRACT_SUGARED_TYPE
#define ABSTRACT_SUGARED_TYPE(Id, Parent) ABSTRACT_TYPE(Id, Parent)
#endif

/// A convenience for determining the range of types.  These will always
/// appear immediately after the last member.
#ifndef TYPE_RANGE
#define TYPE_RANGE(Id, First, Last)
#endif

#ifndef LAST_TYPE
#define LAST_TYPE(Id)
#endif

#if !defined(SINGLETON_TYPE)

TYPE(Error, Type)
UNCHECKED_TYPE(Unresolved, Type)
UNCHECKED_TYPE(Placeholder, Type)
ABSTRACT_TYPE(Builtin, Type)
  ABSTRACT_TYPE(AnyBuiltinInteger, BuiltinType)
    BUILTIN_CONCRETE_TYPE(BuiltinInteger, AnyBuiltinIntegerType)
    BUILTIN_CONCRETE_TYPE(BuiltinIntegerLiteral, AnyBuiltinIntegerType)
    TYPE_RANGE(AnyBuiltinInteger, BuiltinInteger, BuiltinIntegerLiteral)
  BUILTIN_CONCRETE_TYPE(BuiltinExecutor, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinFloat, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinJob, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinPackIndex, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinRawPointer, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinRawUnsafeContinuation, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinNativeObject, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinBridgeObject, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinUnsafeValueBuffer, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinDefaultActorStorage, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinNonDefaultDistributedActorStorage, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinVector, BuiltinType)
  BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinType)
  BUILTIN_CONCRETE_TYPE(BuiltinUnboundGeneric, BuiltinType)
  TYPE_RANGE(Builtin, BuiltinInteger, BuiltinUnboundGeneric)
TYPE(Tuple, Type)
ABSTRACT_TYPE(ReferenceStorage, Type)
#define REF_STORAGE(Name, ...) \
  ARTIFICIAL_TYPE(Name##Storage, ReferenceStorageType)
#define REF_STORAGE_RANGE(First, Last) \
  TYPE_RANGE(ReferenceStorage, First##Storage, Last##Storage)
#include "swift/AST/ReferenceStorage.def"
ABSTRACT_TYPE(AnyGeneric, Type)
  ABSTRACT_TYPE(NominalOrBoundGenericNominal, AnyGenericType)
    ABSTRACT_TYPE(Nominal, NominalOrBoundGenericNominalType)
      TYPE(Enum, NominalType)
      TYPE(Struct, NominalType)
      TYPE(Class, NominalType)
      TYPE(Protocol, NominalType)
      TYPE(BuiltinTuple, NominalType)
      TYPE_RANGE(Nominal, Enum, BuiltinTuple)
    ABSTRACT_TYPE(BoundGeneric, NominalOrBoundGenericNominalType)
      TYPE(BoundGenericClass, BoundGenericType)
      TYPE(BoundGenericEnum, BoundGenericType)
      TYPE(BoundGenericStruct, BoundGenericType)
      TYPE_RANGE(BoundGeneric, BoundGenericClass, BoundGenericStruct)
    TYPE_RANGE(NominalOrBoundGenericNominal, Enum, BoundGenericStruct)
  UNCHECKED_TYPE(UnboundGeneric, AnyGenericType)
  TYPE_RANGE(AnyGeneric, Enum, UnboundGeneric)
ABSTRACT_TYPE(AnyMetatype, Type)
  TYPE(Metatype, AnyMetatypeType)
  TYPE(ExistentialMetatype, AnyMetatypeType)
ALWAYS_CANONICAL_TYPE(Module, Type)
TYPE(DynamicSelf, Type)
ABSTRACT_TYPE(Substitutable, Type)
  ABSTRACT_TYPE(Archetype, SubstitutableType)
    ALWAYS_CANONICAL_TYPE(PrimaryArchetype, ArchetypeType)
    ALWAYS_CANONICAL_TYPE(OpaqueTypeArchetype, ArchetypeType)
    ABSTRACT_TYPE(LocalArchetype, ArchetypeType)
      ALWAYS_CANONICAL_TYPE(ExistentialArchetype, LocalArchetypeType)
      ALWAYS_CANONICAL_TYPE(ElementArchetype, LocalArchetypeType)
      TYPE_RANGE(LocalArchetype, ExistentialArchetype, ElementArchetype)
    ALWAYS_CANONICAL_TYPE(PackArchetype, ArchetypeType)
    TYPE_RANGE(Archetype, PrimaryArchetype, PackArchetype)
  TYPE(GenericTypeParam, SubstitutableType)
  TYPE_RANGE(Substitutable, PrimaryArchetype, GenericTypeParam)
TYPE(DependentMember, Type)
ABSTRACT_TYPE(AnyFunction, Type)
  TYPE(Function, AnyFunctionType)
  TYPE(GenericFunction, AnyFunctionType)
  TYPE_RANGE(AnyFunction, Function, GenericFunction)
ARTIFICIAL_TYPE(SILFunction, Type)
ARTIFICIAL_TYPE(SILBlockStorage, Type)
ARTIFICIAL_TYPE(SILBox, Type)
ARTIFICIAL_TYPE(SILMoveOnlyWrapped, Type)
ALWAYS_CANONICAL_ARTIFICIAL_TYPE(SILPack, Type)
ARTIFICIAL_TYPE(SILToken, Type)
TYPE(ProtocolComposition, Type)
TYPE(ParameterizedProtocol, Type)
TYPE(Existential, Type)
TYPE(LValue, Type)
TYPE(InOut, Type)
TYPE(Pack, Type)
TYPE(PackExpansion, Type)
TYPE(PackElement, Type)
UNCHECKED_TYPE(TypeVariable, Type)
UNCHECKED_TYPE(ErrorUnion, Type)
TYPE(Integer, Type)
ABSTRACT_SUGARED_TYPE(Sugar, Type)
  SUGARED_TYPE(TypeAlias, SugarType)
  SUGARED_TYPE(Locatable, SugarType)
  ABSTRACT_SUGARED_TYPE(SyntaxSugar, SugarType)
    ABSTRACT_SUGARED_TYPE(UnarySyntaxSugar, SyntaxSugarType)
      SUGARED_TYPE(ArraySlice, UnarySyntaxSugarType)
      SUGARED_TYPE(Optional, UnarySyntaxSugarType)
      SUGARED_TYPE(VariadicSequence, UnarySyntaxSugarType)
      TYPE_RANGE(UnarySyntaxSugar, ArraySlice, VariadicSequence)
    SUGARED_TYPE(InlineArray, SyntaxSugarType)
    SUGARED_TYPE(Dictionary, SyntaxSugarType)
    TYPE_RANGE(SyntaxSugar, ArraySlice, Dictionary)
  TYPE_RANGE(Sugar, TypeAlias, Dictionary)
LAST_TYPE(Dictionary) // Sugared types are last to make isa<SugarType>() fast.

#endif

#ifdef SINGLETON_TYPE
SINGLETON_TYPE(IntegerLiteral, BuiltinIntegerLiteral)
SINGLETON_TYPE(Job, BuiltinJob)
SINGLETON_TYPE(Executor, BuiltinExecutor)
SINGLETON_TYPE(PackIndex, BuiltinPackIndex)
SINGLETON_TYPE(RawPointer, BuiltinRawPointer)
SINGLETON_TYPE(RawUnsafeContinuation, BuiltinRawUnsafeContinuation)
SINGLETON_TYPE(NativeObject, BuiltinNativeObject)
SINGLETON_TYPE(BridgeObject, BuiltinBridgeObject)
SINGLETON_TYPE(UnsafeValueBuffer, BuiltinUnsafeValueBuffer)
SINGLETON_TYPE(DefaultActorStorage, BuiltinDefaultActorStorage)
SINGLETON_TYPE(NonDefaultDistributedActorStorage, BuiltinNonDefaultDistributedActorStorage)
SINGLETON_TYPE(SILToken, SILToken)
#undef SINGLETON_TYPE
#endif

#undef TYPE_RANGE
#undef ABSTRACT_SUGARED_TYPE
#undef ABSTRACT_TYPE
#undef UNCHECKED_TYPE
#undef ARTIFICIAL_TYPE
#undef SUGARED_TYPE
#undef BUILTIN_GENERIC_TYPE
#undef BUILTIN_CONCRETE_TYPE
#undef BUILTIN_TYPE
#undef ALWAYS_CANONICAL_TYPE
#undef ALWAYS_CANONICAL_ARTIFICIAL_TYPE
#undef TYPE
#undef LAST_TYPE
