//===--- TypeNodes.def - Swift Type AST Metaprogramming ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://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).

/// 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 PrintAsObjC!

/// 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).

#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 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

UNCHECKED_TYPE(Error, Type)
UNCHECKED_TYPE(Unresolved, Type)
ABSTRACT_TYPE(Builtin, Type)
  BUILTIN_TYPE(BuiltinInteger, BuiltinType)
  BUILTIN_TYPE(BuiltinFloat, BuiltinType)
  BUILTIN_TYPE(BuiltinRawPointer, BuiltinType)
  BUILTIN_TYPE(BuiltinNativeObject, BuiltinType)
  BUILTIN_TYPE(BuiltinBridgeObject, BuiltinType)
  BUILTIN_TYPE(BuiltinUnknownObject, BuiltinType)
  BUILTIN_TYPE(BuiltinUnsafeValueBuffer, BuiltinType)
  BUILTIN_TYPE(BuiltinVector, BuiltinType)
  TYPE_RANGE(Builtin, BuiltinInteger, BuiltinVector)
SUGARED_TYPE(NameAlias, Type)
SUGARED_TYPE(Paren, Type)
TYPE(Tuple, Type)
ABSTRACT_TYPE(ReferenceStorage, Type)
  ARTIFICIAL_TYPE(UnownedStorage, ReferenceStorageType)
  ARTIFICIAL_TYPE(UnmanagedStorage, ReferenceStorageType)
  ARTIFICIAL_TYPE(WeakStorage, ReferenceStorageType)
  TYPE_RANGE(ReferenceStorage, UnownedStorage, WeakStorage)
ABSTRACT_TYPE(Nominal, Type)
  TYPE(Enum, NominalType)
  TYPE(Struct, NominalType)
  TYPE(Class, NominalType)
  ALWAYS_CANONICAL_TYPE(Protocol, NominalType)
  TYPE_RANGE(Nominal, Enum, Protocol)
ABSTRACT_TYPE(AnyMetatype, Type)
  TYPE(Metatype, AnyMetatypeType)
  TYPE(ExistentialMetatype, AnyMetatypeType)
ALWAYS_CANONICAL_TYPE(Module, Type)
TYPE(DynamicSelf, Type)
ABSTRACT_TYPE(Substitutable, Type)
  ALWAYS_CANONICAL_TYPE(Archetype, SubstitutableType)
  ABSTRACT_TYPE(AbstractTypeParam, SubstitutableType)
    TYPE(GenericTypeParam, AbstractTypeParamType)
    SUGARED_TYPE(AssociatedType, AbstractTypeParamType)
    TYPE_RANGE(AbstractTypeParam, GenericTypeParam, AssociatedType)
  TYPE_RANGE(Substitutable, Archetype, AssociatedType)
SUGARED_TYPE(Substituted, Type)
TYPE(DependentMember, Type)
ABSTRACT_TYPE(AnyFunction, Type)
  TYPE(Function, AnyFunctionType)
  TYPE(PolymorphicFunction, AnyFunctionType)
  TYPE(GenericFunction, AnyFunctionType)
  TYPE_RANGE(AnyFunction, Function, GenericFunction)
ARTIFICIAL_TYPE(SILFunction, Type)
ARTIFICIAL_TYPE(SILBlockStorage, Type)
ARTIFICIAL_TYPE(SILBox, Type)
ABSTRACT_SUGARED_TYPE(SyntaxSugar, Type)
  SUGARED_TYPE(ArraySlice, SyntaxSugarType)
  SUGARED_TYPE(Optional, SyntaxSugarType)
  SUGARED_TYPE(ImplicitlyUnwrappedOptional, SyntaxSugarType)
  TYPE_RANGE(SyntaxSugar, ArraySlice, ImplicitlyUnwrappedOptional)
SUGARED_TYPE(Dictionary, Type)
TYPE(ProtocolComposition, Type)
TYPE(LValue, Type)
TYPE(InOut, Type)
UNCHECKED_TYPE(UnboundGeneric, Type)
ABSTRACT_TYPE(BoundGeneric, Type)
  TYPE(BoundGenericClass, BoundGenericType)
  TYPE(BoundGenericEnum, BoundGenericType)
  TYPE(BoundGenericStruct, BoundGenericType)
  TYPE_RANGE(BoundGeneric, BoundGenericClass, BoundGenericStruct)
UNCHECKED_TYPE(TypeVariable, Type)

#undef TYPE_RANGE
#undef ABSTRACT_SUGARED_TYPE
#undef ABSTRACT_TYPE
#undef UNCHECKED_TYPE
#undef ARTIFICIAL_TYPE
#undef SUGARED_TYPE
#undef BUILTIN_TYPE
#undef ALWAYS_CANONICAL_TYPE
#undef TYPE
