// Automatically generated by Digital Mars D Compiler

#pragma once

#include <stddef.h>
#include <stdint.h>

#if !defined(_d_real)
# define _d_real long double
#endif
#if !defined(BEGIN_ENUM)
# define BEGIN_ENUM(name, upper, lower) enum class name {
# define ENUM_KEY(type, name, value, enumName, upper, lower, abbrev) name = value,
# define END_ENUM(name, upper, lower) };
#endif
#if !defined(BEGIN_ENUM_NUMERIC)
# define BEGIN_ENUM_NUMERIC(type, name, upper, lower) enum class name : type {
# define ENUM_KEY_NUMERIC(type, name, value, enumName, upper, lower, abbrev) name = value,
# define END_ENUM_NUMERIC(type, name, upper, lower) };
#endif
#if !defined(BEGIN_ENUM_TYPE)
# define BEGIN_ENUM_TYPE(type, name, upper, lower) namespace name {
# define ENUM_KEY_TYPE(type, name, value, enumName, upper, lower, abbrev) static type const name = value;
# define END_ENUM_TYPE(type, name, upper, lower) };
#endif
#if !defined(BEGIN_ANON_ENUM)
# define BEGIN_ANON_ENUM() enum {
# define ANON_ENUM_KEY(type, name, value) name = value,
# define END_ANON_ENUM() };
#endif
#if !defined(ENUM_CONSTANT_NUMERIC)
# define ENUM_CONSTANT_NUMERIC(type, name, value) enum : type { name = value };
#endif
#if !defined(ENUM_CONSTANT)
# define ENUM_CONSTANT(type, name, value) static type const name = value;
#endif

class RootObject;
BEGIN_ENUM(DYNCAST, DYNCAST, dyncast)
ENUM_KEY(int32_t, object, 0, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, expression, 1, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, dsymbol, 2, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, type, 3, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, identifier, 4, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, tuple, 5, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, parameter, 6, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, statement, 7, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, condition, 8, DYNCAST, DYNCAST, dyncast, DYNCAST)
ENUM_KEY(int32_t, templateparameter, 9, DYNCAST, DYNCAST, dyncast, DYNCAST)
END_ENUM(DYNCAST, DYNCAST, dyncast)

class Visitor;
class Identifier;
class Dsymbol;
class CPPNamespaceDeclaration;
struct Symbol;
struct Loc;
struct Scope;
BEGIN_ENUM(PASS, PASS, pass)
ENUM_KEY(int32_t, init, 0, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, semantic, 1, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, semanticdone, 2, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, semantic2, 3, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, semantic2done, 4, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, semantic3, 5, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, semantic3done, 6, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, inline, 7, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, inlinedone, 8, PASS, PASS, pass, PASS)
ENUM_KEY(int32_t, obj, 9, PASS, PASS, pass, PASS)
END_ENUM(PASS, PASS, pass)

class DeprecatedDeclaration;
class UserAttributeDeclaration;
class UnitTestDeclaration;
class Module;
class TemplateInstance;
struct Ungag;
class ScopeDsymbol;
class AggregateDeclaration;
class LabelDsymbol;
class ClassDeclaration;
class Type;
struct Prot;
class Package;
class EnumMember;
class TemplateDeclaration;
class TemplateMixin;
class ForwardingAttribDeclaration;
class Nspace;
class Declaration;
class StorageClassDeclaration;
class ExpressionDsymbol;
class ThisDeclaration;
class TypeInfoDeclaration;
class TupleDeclaration;
class AliasDeclaration;
class FuncDeclaration;
class FuncAliasDeclaration;
class OverDeclaration;
class FuncLiteralDeclaration;
class CtorDeclaration;
class PostBlitDeclaration;
class DtorDeclaration;
class StaticCtorDeclaration;
class StaticDtorDeclaration;
class SharedStaticCtorDeclaration;
class SharedStaticDtorDeclaration;
class InvariantDeclaration;
class NewDeclaration;
class VarDeclaration;
class VersionSymbol;
class DebugSymbol;
class StructDeclaration;
class UnionDeclaration;
class InterfaceDeclaration;
class ForwardingScopeDsymbol;
class WithScopeSymbol;
class ArrayScopeSymbol;
class Import;
class EnumDeclaration;
class SymbolDeclaration;
class AttribDeclaration;
class AnonDeclaration;
class ProtDeclaration;
class OverloadSet;
class CompileDeclaration;
class DsymbolTable;
BEGIN_ENUM(Kind, KIND, kind)
ENUM_KEY(int32_t, undefined, 0, Kind, KIND, kind, K)
ENUM_KEY(int32_t, none, 1, Kind, KIND, kind, K)
ENUM_KEY(int32_t, private_, 2, Kind, KIND, kind, K)
ENUM_KEY(int32_t, package_, 3, Kind, KIND, kind, K)
ENUM_KEY(int32_t, protected_, 4, Kind, KIND, kind, K)
ENUM_KEY(int32_t, public_, 5, Kind, KIND, kind, K)
ENUM_KEY(int32_t, export_, 6, Kind, KIND, kind, K)
END_ENUM(Kind, KIND, kind)

struct BitArray;
BEGIN_ENUM(CPPMANGLE, CPPMANGLE, cppmangle)
ENUM_KEY(int32_t, def, 0, CPPMANGLE, CPPMANGLE, cppmangle, CPPMANGLE)
ENUM_KEY(int32_t, asStruct, 1, CPPMANGLE, CPPMANGLE, cppmangle, CPPMANGLE)
ENUM_KEY(int32_t, asClass, 2, CPPMANGLE, CPPMANGLE, cppmangle, CPPMANGLE)
END_ENUM(CPPMANGLE, CPPMANGLE, cppmangle)

class AliasThis;
class Expression;
class TypeTuple;
class TemplateParameter;
class Statement;
struct BaseClass;
class Parameter;
class Initializer;
class Catch;
class CaseStatement;
class ScopeStatement;
class GotoCaseStatement;
class ReturnStatement;
class GotoStatement;
struct Ensure;
BEGIN_ENUM(LINK, LINK, link)
ENUM_KEY(int32_t, default_, 0, LINK, LINK, link, LINK)
ENUM_KEY(int32_t, d, 1, LINK, LINK, link, LINK)
ENUM_KEY(int32_t, c, 2, LINK, LINK, link, LINK)
ENUM_KEY(int32_t, cpp, 3, LINK, LINK, link, LINK)
ENUM_KEY(int32_t, windows, 4, LINK, LINK, link, LINK)
ENUM_KEY(int32_t, pascal, 5, LINK, LINK, link, LINK)
ENUM_KEY(int32_t, objc, 6, LINK, LINK, link, LINK)
ENUM_KEY(int32_t, system, 7, LINK, LINK, link, LINK)
END_ENUM(LINK, LINK, link)

class LinkDeclaration;
class Condition;
class StaticForeach;
BEGIN_ENUM_NUMERIC(uint8_t, BUILTIN, BUILTIN, builtin)
ENUM_KEY_NUMERIC(uint8_t, unknown, 255u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, unimp, 0u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, gcc, 1u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, llvm, 2u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, sin, 3u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, cos, 4u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, tan, 5u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, sqrt, 6u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, fabs, 7u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, ldexp, 8u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, log, 9u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, log2, 10u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, log10, 11u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, exp, 12u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, expm1, 13u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, exp2, 14u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, round, 15u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, floor, 16u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, ceil, 17u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, trunc, 18u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, copysign, 19u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, pow, 20u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, fmin, 21u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, fmax, 22u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, fma, 23u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, isnan, 24u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, isinfinity, 25u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, isfinite, 26u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, bsf, 27u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, bsr, 28u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, bswap, 29u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, popcnt, 30u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, yl2x, 31u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, yl2xp1, 32u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, toPrecFloat, 33u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, toPrecDouble, 34u, BUILTIN, BUILTIN, builtin, BUILTIN)
ENUM_KEY_NUMERIC(uint8_t, toPrecReal, 35u, BUILTIN, BUILTIN, builtin, BUILTIN)
END_ENUM_NUMERIC(uint8_t, BUILTIN, BUILTIN, builtin)

struct UnionExp;
struct complex_t;
class DebugCondition;
class VersionCondition;
class ForeachStatement;
class ForeachRangeStatement;
BEGIN_ENUM_NUMERIC(uint8_t, TOK, TOK, tok)
ENUM_KEY_NUMERIC(uint8_t, reserved, 0u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, leftParentheses, 1u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, rightParentheses, 2u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, leftBracket, 3u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, rightBracket, 4u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, leftCurly, 5u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, rightCurly, 6u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, colon, 7u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, negate, 8u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, semicolon, 9u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dotDotDot, 10u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, endOfFile, 11u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, cast_, 12u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, null_, 13u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, assert_, 14u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, true_, 15u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, false_, 16u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, array, 17u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, call, 18u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, address, 19u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, type, 20u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, throw_, 21u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, new_, 22u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, delete_, 23u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, star, 24u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, symbolOffset, 25u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, variable, 26u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dotVariable, 27u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dotIdentifier, 28u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dotTemplateInstance, 29u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dotType, 30u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, slice, 31u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, arrayLength, 32u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, version_, 33u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, module_, 34u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dollar, 35u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, template_, 36u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dotTemplateDeclaration, 37u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, declaration, 38u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, typeof_, 39u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, pragma_, 40u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dSymbol, 41u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, typeid_, 42u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uadd, 43u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, remove, 44u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, newAnonymousClass, 45u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, comment, 46u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, arrayLiteral, 47u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, assocArrayLiteral, 48u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, structLiteral, 49u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, classReference, 50u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, thrownException, 51u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, delegatePointer, 52u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, delegateFunctionPointer, 53u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, lessThan, 54u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, greaterThan, 55u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, lessOrEqual, 56u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, greaterOrEqual, 57u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, equal, 58u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, notEqual, 59u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, identity, 60u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, notIdentity, 61u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, index, 62u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, is_, 63u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, leftShift, 64u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, rightShift, 65u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, leftShiftAssign, 66u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, rightShiftAssign, 67u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, unsignedRightShift, 68u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, unsignedRightShiftAssign, 69u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, concatenate, 70u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, concatenateAssign, 71u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, concatenateElemAssign, 72u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, concatenateDcharAssign, 73u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, add, 74u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, min, 75u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, addAssign, 76u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, minAssign, 77u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, mul, 78u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, div, 79u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, mod, 80u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, mulAssign, 81u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, divAssign, 82u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, modAssign, 83u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, and, 84u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, or, 85u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, xor, 86u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, andAssign, 87u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, orAssign, 88u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, xorAssign, 89u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, assign, 90u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, not, 91u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, tilde, 92u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, plusPlus, 93u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, minusMinus, 94u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, construct, 95u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, blit, 96u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dot, 97u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, arrow, 98u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, comma, 99u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, question, 100u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, andAnd, 101u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, orOr, 102u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, prePlusPlus, 103u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, preMinusMinus, 104u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int32Literal, 105u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns32Literal, 106u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int64Literal, 107u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns64Literal, 108u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int128Literal, 109u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns128Literal, 110u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, float32Literal, 111u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, float64Literal, 112u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, float80Literal, 113u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, imaginary32Literal, 114u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, imaginary64Literal, 115u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, imaginary80Literal, 116u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, charLiteral, 117u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, wcharLiteral, 118u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dcharLiteral, 119u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, identifier, 120u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, string_, 121u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, hexadecimalString, 122u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, this_, 123u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, super_, 124u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, halt, 125u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, tuple, 126u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, error, 127u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, void_, 128u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int8, 129u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns8, 130u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int16, 131u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns16, 132u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int32, 133u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns32, 134u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int64, 135u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns64, 136u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, int128, 137u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, uns128, 138u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, float32, 139u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, float64, 140u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, float80, 141u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, imaginary32, 142u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, imaginary64, 143u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, imaginary80, 144u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, complex32, 145u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, complex64, 146u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, complex80, 147u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, char_, 148u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, wchar_, 149u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, dchar_, 150u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, bool_, 151u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, struct_, 152u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, class_, 153u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, interface_, 154u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, union_, 155u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, enum_, 156u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, import_, 157u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, alias_, 158u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, override_, 159u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, delegate_, 160u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, function_, 161u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, mixin_, 162u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, align_, 163u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, extern_, 164u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, private_, 165u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, protected_, 166u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, public_, 167u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, export_, 168u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, static_, 169u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, final_, 170u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, const_, 171u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, abstract_, 172u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, debug_, 173u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, deprecated_, 174u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, in_, 175u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, out_, 176u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, inout_, 177u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, lazy_, 178u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, auto_, 179u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, package_, 180u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, immutable_, 181u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, if_, 182u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, else_, 183u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, while_, 184u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, for_, 185u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, do_, 186u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, switch_, 187u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, case_, 188u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, default_, 189u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, break_, 190u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, continue_, 191u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, with_, 192u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, synchronized_, 193u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, return_, 194u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, goto_, 195u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, try_, 196u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, catch_, 197u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, finally_, 198u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, asm_, 199u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, foreach_, 200u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, foreach_reverse_, 201u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, scope_, 202u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, onScopeExit, 203u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, onScopeFailure, 204u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, onScopeSuccess, 205u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, invariant_, 206u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, unittest_, 207u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, argumentTypes, 208u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, ref_, 209u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, macro_, 210u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, parameters, 211u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, traits, 212u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, overloadSet, 213u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, pure_, 214u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, nothrow_, 215u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, gshared, 216u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, line, 217u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, file, 218u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, fileFullPath, 219u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, moduleString, 220u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, functionString, 221u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, prettyFunction, 222u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, shared_, 223u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, at, 224u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, pow, 225u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, powAssign, 226u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, goesTo, 227u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, vector, 228u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, pound, 229u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, interval, 230u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, voidExpression, 231u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, cantExpression, 232u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, showCtfeContext, 233u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, objcClassReference, 234u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, vectorArray, 235u, TOK, TOK, tok, TOK)
ENUM_KEY_NUMERIC(uint8_t, max_, 236u, TOK, TOK, tok, TOK)
END_ENUM_NUMERIC(uint8_t, TOK, TOK, tok)

class StringExp;
class TupleExp;
BEGIN_ENUM(MATCH, MATCH, match)
ENUM_KEY(int32_t, nomatch, 0, MATCH, MATCH, match, MATCH)
ENUM_KEY(int32_t, convert, 1, MATCH, MATCH, match, MATCH)
ENUM_KEY(int32_t, constant, 2, MATCH, MATCH, match, MATCH)
ENUM_KEY(int32_t, exact, 3, MATCH, MATCH, match, MATCH)
END_ENUM(MATCH, MATCH, match)

BEGIN_ENUM(Modifiable, MODIFIABLE, modifiable)
ENUM_KEY(int32_t, no, 0, Modifiable, MODIFIABLE, modifiable, M)
ENUM_KEY(int32_t, yes, 1, Modifiable, MODIFIABLE, modifiable, M)
ENUM_KEY(int32_t, initialization, 2, Modifiable, MODIFIABLE, modifiable, M)
END_ENUM(Modifiable, MODIFIABLE, modifiable)

class IntegerExp;
class ErrorExp;
class VoidInitExp;
class RealExp;
class ComplexExp;
class IdentifierExp;
class DollarExp;
class DsymbolExp;
class ThisExp;
class SuperExp;
class NullExp;
class ArrayLiteralExp;
class AssocArrayLiteralExp;
class StructLiteralExp;
class TypeExp;
class ScopeExp;
class TemplateExp;
class NewExp;
class NewAnonClassExp;
class SymOffExp;
class VarExp;
class OverExp;
class FuncExp;
class DeclarationExp;
class TypeidExp;
class TraitsExp;
class HaltExp;
class IsExp;
class CompileExp;
class ImportExp;
class AssertExp;
class DotIdExp;
class DotTemplateExp;
class DotVarExp;
class DotTemplateInstanceExp;
class DelegateExp;
class DotTypeExp;
class CallExp;
class AddrExp;
class PtrExp;
class NegExp;
class UAddExp;
class ComExp;
class NotExp;
class DeleteExp;
class CastExp;
class VectorExp;
class VectorArrayExp;
class SliceExp;
class ArrayLengthExp;
class ArrayExp;
class DotExp;
class CommaExp;
class IntervalExp;
class DelegatePtrExp;
class DelegateFuncptrExp;
class IndexExp;
class PostExp;
class PreExp;
class AssignExp;
class ConstructExp;
class BlitExp;
class AddAssignExp;
class MinAssignExp;
class MulAssignExp;
class DivAssignExp;
class ModAssignExp;
class AndAssignExp;
class OrAssignExp;
class XorAssignExp;
class PowAssignExp;
class ShlAssignExp;
class ShrAssignExp;
class UshrAssignExp;
class CatAssignExp;
class CatElemAssignExp;
class CatDcharAssignExp;
class AddExp;
class MinExp;
class CatExp;
class MulExp;
class DivExp;
class ModExp;
class PowExp;
class ShlExp;
class ShrExp;
class UshrExp;
class AndExp;
class OrExp;
class XorExp;
class LogicalExp;
class InExp;
class RemoveExp;
class EqualExp;
class IdentityExp;
class CondExp;
class DefaultInitExp;
class FileInitExp;
class LineInitExp;
class ModuleInitExp;
class FuncInitExp;
class PrettyFuncInitExp;
class ClassReferenceExp;
class TypeInfoClassDeclaration;
struct ObjcClassDeclaration;
class TypeFunction;
struct IntRange;
class TypeInfoStructDeclaration;
class TypeInfoInterfaceDeclaration;
class TypeInfoPointerDeclaration;
class TypeInfoArrayDeclaration;
class TypeInfoStaticArrayDeclaration;
class TypeInfoAssociativeArrayDeclaration;
class TypeInfoEnumDeclaration;
class TypeInfoFunctionDeclaration;
class TypeInfoDelegateDeclaration;
class TypeInfoTupleDeclaration;
class TypeInfoConstDeclaration;
class TypeInfoInvariantDeclaration;
class TypeInfoSharedDeclaration;
class TypeInfoWildDeclaration;
class TypeInfoVectorDeclaration;
struct Macro;
struct OutBuffer;
struct ModuleDeclaration;
struct FileName;
struct FileBuffer;
struct MacroTable;
struct Escape;
struct ReadResult;
class WithStatement;
class Tuple;
struct TemplatePrevious;
class TemplateTupleParameter;
struct Mcache;
struct TYPE;
class TypeBasic;
class TypeError;
class TypeVector;
class TypeSArray;
class TypeDArray;
class TypeAArray;
class TypePointer;
class TypeReference;
class TypeDelegate;
class TypeIdentifier;
class TypeInstance;
class TypeTypeof;
class TypeReturn;
class TypeStruct;
class TypeEnum;
class TypeClass;
class TypeSlice;
class TypeNull;
class TypeMixin;
class TypeTraits;
class TemplateTypeParameter;
class TemplateValueParameter;
class TemplateAliasParameter;
class TemplateThisParameter;
class TypeQualified;
class StaticAssert;
class AlignDeclaration;
class CPPMangleDeclaration;
class PragmaDeclaration;
class ConditionalDeclaration;
class StaticForeachDeclaration;
class StaticIfDeclaration;
class ImportStatement;
class LabelStatement;
class StaticAssertStatement;
class CompileStatement;
class WhileStatement;
class ForStatement;
class DoStatement;
class IfStatement;
class ScopeGuardStatement;
class ConditionalStatement;
class StaticForeachStatement;
class PragmaStatement;
class SwitchStatement;
class CaseRangeStatement;
class DefaultStatement;
class BreakStatement;
class ContinueStatement;
class GotoDefaultStatement;
class SynchronizedStatement;
class TryCatchStatement;
class TryFinallyStatement;
class ThrowStatement;
class AsmStatement;
class ExpStatement;
class CompoundStatement;
class CompoundDeclarationStatement;
class CompoundAsmStatement;
class InlineAsmStatement;
class GccAsmStatement;
class TypeNext;
class TypeArray;
class UnaExp;
class BinExp;
class SymbolExp;
class CmpExp;
class BinAssignExp;
class StaticIfCondition;
class DVCondition;
class ExpInitializer;
class StructInitializer;
class ArrayInitializer;
class VoidInitializer;
class ErrorStatement;
class PeelStatement;
class UnrolledLoopStatement;
class SwitchErrorStatement;
class DebugStatement;
class DtorExpStatement;
class ForwardingStatement;
class ErrorInitializer;
class ObjcClassReferenceExp;
class ThrownExceptionExp;
struct ASTCodegen;
union __AnonStruct__u;
BEGIN_ENUM(PINLINE, PINLINE, pinline)
ENUM_KEY(int32_t, default_, 0, PINLINE, PINLINE, pinline, PINLINE)
ENUM_KEY(int32_t, never, 1, PINLINE, PINLINE, pinline, PINLINE)
ENUM_KEY(int32_t, always, 2, PINLINE, PINLINE, pinline, PINLINE)
END_ENUM(PINLINE, PINLINE, pinline)

struct ObjcFuncDeclaration;
struct ObjcSelector;
BEGIN_ENUM_NUMERIC(uint8_t, PURE, PURE, pure)
ENUM_KEY_NUMERIC(uint8_t, impure, 0u, PURE, PURE, pure, PURE)
ENUM_KEY_NUMERIC(uint8_t, fwdref, 1u, PURE, PURE, pure, PURE)
ENUM_KEY_NUMERIC(uint8_t, weak, 2u, PURE, PURE, pure, PURE)
ENUM_KEY_NUMERIC(uint8_t, const_, 3u, PURE, PURE, pure, PURE)
ENUM_KEY_NUMERIC(uint8_t, strong, 4u, PURE, PURE, pure, PURE)
END_ENUM_NUMERIC(uint8_t, PURE, PURE, pure)

struct ParameterList;
BEGIN_ENUM_NUMERIC(uint8_t, VarArg, VARARG, vararg)
ENUM_KEY_NUMERIC(uint8_t, none, 0u, VarArg, VARARG, vararg, VA)
ENUM_KEY_NUMERIC(uint8_t, variadic, 1u, VarArg, VARARG, vararg, VA)
ENUM_KEY_NUMERIC(uint8_t, typesafe, 2u, VarArg, VARARG, vararg, VA)
END_ENUM_NUMERIC(uint8_t, VarArg, VARARG, vararg)

BEGIN_ENUM_NUMERIC(uint32_t, JsonFieldFlags, JSONFIELDFLAGS, jsonfieldflags)
ENUM_KEY_NUMERIC(uint32_t, none, 0u, JsonFieldFlags, JSONFIELDFLAGS, jsonfieldflags, JFF)
ENUM_KEY_NUMERIC(uint32_t, compilerInfo, 1u, JsonFieldFlags, JSONFIELDFLAGS, jsonfieldflags, JFF)
ENUM_KEY_NUMERIC(uint32_t, buildInfo, 2u, JsonFieldFlags, JSONFIELDFLAGS, jsonfieldflags, JFF)
ENUM_KEY_NUMERIC(uint32_t, modules, 4u, JsonFieldFlags, JSONFIELDFLAGS, jsonfieldflags, JFF)
ENUM_KEY_NUMERIC(uint32_t, semantics, 8u, JsonFieldFlags, JSONFIELDFLAGS, jsonfieldflags, JFF)
END_ENUM_NUMERIC(uint32_t, JsonFieldFlags, JSONFIELDFLAGS, jsonfieldflags)

class Library;
struct _IO_FILE;
struct ObNode;
class StoppableVisitor;
struct Token;
struct code;
struct TargetC;
struct TargetCPP;
struct TargetObjC;
struct Param;
struct Target;
struct Global;
struct Mem;
class Object;
class TypeInfo_Class;
class TypeInfo;

class RootObject
{
public:
    RootObject();
    virtual bool equals(const RootObject* const o) const;
    virtual const char* toChars() const;
    virtual DYNCAST dyncast() const;
};

class ASTNode : public RootObject
{
public:
    virtual void accept(Visitor* v) = 0;
    ASTNode();
};

struct Loc
{
    const char* filename;
    uint32_t linnum;
    uint32_t charnum;
    const char* toChars(bool showColumns, uint8_t messageStyle) const;
    bool equals(const Loc& loc) const;
    Loc() :
        filename(),
        linnum(),
        charnum()
    {
    }
};

class Dsymbol : public ASTNode
{
public:
    Identifier* ident;
    Dsymbol* parent;
    CPPNamespaceDeclaration* cppnamespace;
    Symbol* csym;
    Symbol* isym;
    char* comment;
    Loc loc;
    Scope* _scope;
    char* prettystring;
    bool errors;
    PASS semanticRun;
    DeprecatedDeclaration* depdecl;
    UserAttributeDeclaration* userAttribDecl;
    UnitTestDeclaration* ddocUnittest;
    static Dsymbol* create(Identifier* ident);
    const char* toChars() const;
    virtual const char* toPrettyCharsHelper();
    const Loc getLoc();
    const char* locToChars();
    bool equals(const RootObject* const o) const;
    bool isAnonymous() const;
    void error(const Loc& loc, const char* format, ...);
    void error(const char* format, ...);
    void deprecation(const Loc& loc, const char* format, ...);
    void deprecation(const char* format, ...);
    bool checkDeprecated(const Loc& loc, Scope* sc);
    Module* getModule();
    Module* getAccessModule();
    Dsymbol* pastMixin();
    Dsymbol* toParent();
    Dsymbol* toParent2();
    Dsymbol* toParentDecl();
    Dsymbol* toParentLocal();
    Dsymbol* toParentDeclImpl(bool localOnly);
    Dsymbol* toParentP(Dsymbol* p1, Dsymbol* p2);
    TemplateInstance* isInstantiated();
    bool followInstantiationContext(Dsymbol* p1, Dsymbol* p2);
    TemplateInstance* isSpeculative();
    Ungag ungagSpeculative() const;
    DYNCAST dyncast() const;
    virtual Identifier* getIdent();
    virtual const char* toPrettyChars(bool QualifyTypes = false);
    virtual const char* kind() const;
    virtual Dsymbol* toAlias();
    virtual Dsymbol* toAlias2();
    virtual void addMember(Scope* sc, ScopeDsymbol* sds);
    virtual void setScope(Scope* sc);
    virtual void importAll(Scope* sc);
    virtual Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 0);
    virtual bool overloadInsert(Dsymbol* s);
    virtual d_uns64 size(const Loc& loc);
    virtual bool isforwardRef();
    virtual AggregateDeclaration* isThis();
    virtual bool isExport() const;
    virtual bool isImportedSymbol() const;
    virtual bool isDeprecated() const;
    virtual bool isOverloadable() const;
    virtual LabelDsymbol* isLabel();
    AggregateDeclaration* isMember();
    AggregateDeclaration* isMember2();
    AggregateDeclaration* isMemberDecl();
    AggregateDeclaration* isMemberLocal();
    ClassDeclaration* isClassMember();
    virtual Type* getType();
    virtual bool needThis();
    virtual Prot prot();
    virtual Dsymbol* syntaxCopy(Dsymbol* s);
    virtual bool oneMember(Dsymbol** ps, Identifier* ident);
    virtual void setFieldOffset(AggregateDeclaration* ad, uint32_t* poffset, bool isunion);
    virtual bool hasPointers();
    virtual bool hasStaticCtorOrDtor();
    virtual void addLocalClass(Array<ClassDeclaration*>* _param_0);
    virtual void addObjcSymbols(Array<ClassDeclaration*>* classes, Array<ClassDeclaration*>* categories);
    virtual void checkCtorConstInit();
    virtual void addComment(const char* comment);
    bool inNonRoot();
    void accept(Visitor* v);
    virtual Package* isPackage();
    virtual Module* isModule();
    virtual EnumMember* isEnumMember();
    virtual TemplateDeclaration* isTemplateDeclaration();
    virtual TemplateInstance* isTemplateInstance();
    virtual TemplateMixin* isTemplateMixin();
    virtual ForwardingAttribDeclaration* isForwardingAttribDeclaration();
    virtual Nspace* isNspace();
    virtual Declaration* isDeclaration();
    virtual StorageClassDeclaration* isStorageClassDeclaration();
    virtual ExpressionDsymbol* isExpressionDsymbol();
    virtual ThisDeclaration* isThisDeclaration();
    virtual TypeInfoDeclaration* isTypeInfoDeclaration();
    virtual TupleDeclaration* isTupleDeclaration();
    virtual AliasDeclaration* isAliasDeclaration();
    virtual AggregateDeclaration* isAggregateDeclaration();
    virtual FuncDeclaration* isFuncDeclaration();
    virtual FuncAliasDeclaration* isFuncAliasDeclaration();
    virtual OverDeclaration* isOverDeclaration();
    virtual FuncLiteralDeclaration* isFuncLiteralDeclaration();
    virtual CtorDeclaration* isCtorDeclaration();
    virtual PostBlitDeclaration* isPostBlitDeclaration();
    virtual DtorDeclaration* isDtorDeclaration();
    virtual StaticCtorDeclaration* isStaticCtorDeclaration();
    virtual StaticDtorDeclaration* isStaticDtorDeclaration();
    virtual SharedStaticCtorDeclaration* isSharedStaticCtorDeclaration();
    virtual SharedStaticDtorDeclaration* isSharedStaticDtorDeclaration();
    virtual InvariantDeclaration* isInvariantDeclaration();
    virtual UnitTestDeclaration* isUnitTestDeclaration();
    virtual NewDeclaration* isNewDeclaration();
    virtual VarDeclaration* isVarDeclaration();
    virtual VersionSymbol* isVersionSymbol();
    virtual DebugSymbol* isDebugSymbol();
    virtual ClassDeclaration* isClassDeclaration();
    virtual StructDeclaration* isStructDeclaration();
    virtual UnionDeclaration* isUnionDeclaration();
    virtual InterfaceDeclaration* isInterfaceDeclaration();
    virtual ScopeDsymbol* isScopeDsymbol();
    virtual ForwardingScopeDsymbol* isForwardingScopeDsymbol();
    virtual WithScopeSymbol* isWithScopeSymbol();
    virtual ArrayScopeSymbol* isArrayScopeSymbol();
    virtual Import* isImport();
    virtual EnumDeclaration* isEnumDeclaration();
    virtual SymbolDeclaration* isSymbolDeclaration();
    virtual AttribDeclaration* isAttribDeclaration();
    virtual AnonDeclaration* isAnonDeclaration();
    virtual CPPNamespaceDeclaration* isCPPNamespaceDeclaration();
    virtual ProtDeclaration* isProtDeclaration();
    virtual OverloadSet* isOverloadSet();
    virtual CompileDeclaration* isCompileDeclaration();
};

struct BitArray
{
    typedef uint64_t Chunk_t;
    ENUM_CONSTANT_NUMERIC(uint64_t, ChunkSize, 8LLU)

    ENUM_CONSTANT_NUMERIC(uint64_t, BitsPerChunk, 64LLU)

    size_t len;
    uint64_t* ptr;
    BitArray()
    {
    }
};

class ScopeDsymbol : public Dsymbol
{
public:
    Array<Dsymbol*>* members;
    DsymbolTable* symtab;
    uint32_t endlinnum;
    Array<Dsymbol*>* importedScopes;
    Kind* prots;
    BitArray accessiblePackages;
    BitArray privateAccessiblePackages;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    virtual void importScope(Dsymbol* s, Prot protection);
    virtual bool isPackageAccessible(Package* p, Prot protection, int32_t flags = 0);
    bool isforwardRef();
    static void multiplyDefined(const Loc& loc, Dsymbol* s1, Dsymbol* s2);
    const char* kind() const;
    FuncDeclaration* findGetMembers();
    virtual Dsymbol* symtabInsert(Dsymbol* s);
    virtual Dsymbol* symtabLookup(Dsymbol* s, Identifier* id);
    bool hasStaticCtorOrDtor();
    ScopeDsymbol* isScopeDsymbol();
    void accept(Visitor* v);
    ~ScopeDsymbol();
};

struct Prot
{
    Kind kind;
    Package* pkg;
    bool isMoreRestrictiveThan(const Prot other) const;
    bool opEquals(const Prot& other) const;
    bool isSubsetOf(const Prot& parent) const;
    Prot() :
        pkg()
    {
    }
};

class Expression : public ASTNode
{
public:
    TOK op;
    uint8_t size;
    uint8_t parens;
    Type* type;
    Loc loc;
    static void _init();
    static void deinitialize();
    Expression* copy();
    virtual Expression* syntaxCopy();
    DYNCAST dyncast() const;
    const char* toChars() const;
    void error(const char* format, ...) const;
    void errorSupplemental(const char* format, ...);
    void warning(const char* format, ...) const;
    void deprecation(const char* format, ...) const;
    virtual dinteger_t toInteger();
    virtual uinteger_t toUInteger();
    virtual _d_real toReal();
    virtual _d_real toImaginary();
    virtual complex_t toComplex();
    virtual StringExp* toStringExp();
    virtual TupleExp* toTupleExp();
    virtual bool isLvalue();
    virtual Expression* toLvalue(Scope* sc, Expression* e);
    virtual Expression* modifiableLvalue(Scope* sc, Expression* e);
    Expression* implicitCastTo(Scope* sc, Type* t);
    MATCH implicitConvTo(Type* t);
    Expression* castTo(Scope* sc, Type* t);
    virtual Expression* resolveLoc(const Loc& loc, Scope* sc);
    virtual bool checkType();
    virtual bool checkValue();
    bool checkDeprecated(Scope* sc, Dsymbol* s);
    static bool checkImpure(Scope* sc);
    virtual Modifiable checkModifiable(Scope* sc, int32_t flag = 0);
    virtual Expression* toBoolean(Scope* sc);
    virtual Expression* addDtorHook(Scope* sc);
    Expression* addressOf();
    Expression* deref();
    Expression* optimize(int32_t result, bool keepLvalue = false);
    Expression* ctfeInterpret();
    int32_t isConst();
    virtual bool isBool(bool result);
    virtual bool hasCode();
    IntegerExp* isIntegerExp();
    ErrorExp* isErrorExp();
    VoidInitExp* isVoidInitExp();
    RealExp* isRealExp();
    ComplexExp* isComplexExp();
    IdentifierExp* isIdentifierExp();
    DollarExp* isDollarExp();
    DsymbolExp* isDsymbolExp();
    ThisExp* isThisExp();
    SuperExp* isSuperExp();
    NullExp* isNullExp();
    StringExp* isStringExp();
    TupleExp* isTupleExp();
    ArrayLiteralExp* isArrayLiteralExp();
    AssocArrayLiteralExp* isAssocArrayLiteralExp();
    StructLiteralExp* isStructLiteralExp();
    TypeExp* isTypeExp();
    ScopeExp* isScopeExp();
    TemplateExp* isTemplateExp();
    NewExp* isNewExp();
    NewAnonClassExp* isNewAnonClassExp();
    SymOffExp* isSymOffExp();
    VarExp* isVarExp();
    OverExp* isOverExp();
    FuncExp* isFuncExp();
    DeclarationExp* isDeclarationExp();
    TypeidExp* isTypeidExp();
    TraitsExp* isTraitsExp();
    HaltExp* isHaltExp();
    IsExp* isExp();
    CompileExp* isCompileExp();
    ImportExp* isImportExp();
    AssertExp* isAssertExp();
    DotIdExp* isDotIdExp();
    DotTemplateExp* isDotTemplateExp();
    DotVarExp* isDotVarExp();
    DotTemplateInstanceExp* isDotTemplateInstanceExp();
    DelegateExp* isDelegateExp();
    DotTypeExp* isDotTypeExp();
    CallExp* isCallExp();
    AddrExp* isAddrExp();
    PtrExp* isPtrExp();
    NegExp* isNegExp();
    UAddExp* isUAddExp();
    ComExp* isComExp();
    NotExp* isNotExp();
    DeleteExp* isDeleteExp();
    CastExp* isCastExp();
    VectorExp* isVectorExp();
    VectorArrayExp* isVectorArrayExp();
    SliceExp* isSliceExp();
    ArrayLengthExp* isArrayLengthExp();
    ArrayExp* isArrayExp();
    DotExp* isDotExp();
    CommaExp* isCommaExp();
    IntervalExp* isIntervalExp();
    DelegatePtrExp* isDelegatePtrExp();
    DelegateFuncptrExp* isDelegateFuncptrExp();
    IndexExp* isIndexExp();
    PostExp* isPostExp();
    PreExp* isPreExp();
    AssignExp* isAssignExp();
    ConstructExp* isConstructExp();
    BlitExp* isBlitExp();
    AddAssignExp* isAddAssignExp();
    MinAssignExp* isMinAssignExp();
    MulAssignExp* isMulAssignExp();
    DivAssignExp* isDivAssignExp();
    ModAssignExp* isModAssignExp();
    AndAssignExp* isAndAssignExp();
    OrAssignExp* isOrAssignExp();
    XorAssignExp* isXorAssignExp();
    PowAssignExp* isPowAssignExp();
    ShlAssignExp* isShlAssignExp();
    ShrAssignExp* isShrAssignExp();
    UshrAssignExp* isUshrAssignExp();
    CatAssignExp* isCatAssignExp();
    CatElemAssignExp* isCatElemAssignExp();
    CatDcharAssignExp* isCatDcharAssignExp();
    AddExp* isAddExp();
    MinExp* isMinExp();
    CatExp* isCatExp();
    MulExp* isMulExp();
    DivExp* isDivExp();
    ModExp* isModExp();
    PowExp* isPowExp();
    ShlExp* isShlExp();
    ShrExp* isShrExp();
    UshrExp* isUshrExp();
    AndExp* isAndExp();
    OrExp* isOrExp();
    XorExp* isXorExp();
    LogicalExp* isLogicalExp();
    InExp* isInExp();
    RemoveExp* isRemoveExp();
    EqualExp* isEqualExp();
    IdentityExp* isIdentityExp();
    CondExp* isCondExp();
    DefaultInitExp* isDefaultInitExp();
    FileInitExp* isFileInitExp();
    LineInitExp* isLineInitExp();
    ModuleInitExp* isModuleInitExp();
    FuncInitExp* isFuncInitExp();
    PrettyFuncInitExp* isPrettyFuncInitExp();
    ClassReferenceExp* isClassReferenceExp();
    void accept(Visitor* v);
};

struct ObjcClassDeclaration
{
    bool isMeta;
    bool isExtern;
    Identifier* identifier;
    ClassDeclaration* classDeclaration;
    ClassDeclaration* metaclass;
    Array<FuncDeclaration*>* methodList;
    bool isRootClass() const;
    ObjcClassDeclaration() :
        isMeta(false),
        isExtern(false),
        identifier(),
        classDeclaration(),
        metaclass(),
        methodList()
    {
    }
};

struct FileName
{
    DArray< const char > str;
    static bool equals(const char* name1, const char* name2);
    static bool absolute(const char* name);
    static const char* toAbsolute(const char* name, const char* base);
    static const char* ext(const char* str);
    const char* ext() const;
    static const char* removeExt(const char* str);
    static const char* name(const char* str);
    const char* name() const;
    static const char* path(const char* str);
    static const char* combine(const char* path, const char* name);
    static Array<const char*>* splitPath(const char* path);
    static const char* defaultExt(const char* name, const char* ext);
    static const char* forceExt(const char* name, const char* ext);
    static bool equalsExt(const char* name, const char* ext);
    bool equalsExt(const char* ext) const;
    static const char* searchPath(Array<const char*>* path, const char* name, bool cwd);
    static const char* safeSearchPath(Array<const char*>* path, const char* name);
    static int32_t exists(const char* name);
    static bool ensurePathExists(const char* path);
    static const char* canonicalName(const char* name);
    static void free(const char* str);
    const char* toChars() const;
    FileName()
    {
    }
};

class Type : public ASTNode
{
public:
    uint8_t ty;
    uint8_t mod;
    char* deco;
    struct Mcache
    {
        Type* cto;
        Type* ito;
        Type* sto;
        Type* scto;
        Type* wto;
        Type* wcto;
        Type* swto;
        Type* swcto;
        Mcache() :
            cto(),
            ito(),
            sto(),
            scto(),
            wto(),
            wcto(),
            swto(),
            swcto()
        {
        }
    };

    Mcache* mcache;
    Type* pto;
    Type* rto;
    Type* arrayof;
    TypeInfoDeclaration* vtinfo;
    TYPE* ctype;
    static Type* tvoid;
    static Type* tint8;
    static Type* tuns8;
    static Type* tint16;
    static Type* tuns16;
    static Type* tint32;
    static Type* tuns32;
    static Type* tint64;
    static Type* tuns64;
    static Type* tint128;
    static Type* tuns128;
    static Type* tfloat32;
    static Type* tfloat64;
    static Type* tfloat80;
    static Type* timaginary32;
    static Type* timaginary64;
    static Type* timaginary80;
    static Type* tcomplex32;
    static Type* tcomplex64;
    static Type* tcomplex80;
    static Type* tbool;
    static Type* tchar;
    static Type* twchar;
    static Type* tdchar;
    static Type* tshiftcnt;
    static Type* tvoidptr;
    static Type* tstring;
    static Type* twstring;
    static Type* tdstring;
    static Type* terror;
    static Type* tnull;
    static Type* tsize_t;
    static Type* tptrdiff_t;
    static Type* thash_t;
    static ClassDeclaration* dtypeinfo;
    static ClassDeclaration* typeinfoclass;
    static ClassDeclaration* typeinfointerface;
    static ClassDeclaration* typeinfostruct;
    static ClassDeclaration* typeinfopointer;
    static ClassDeclaration* typeinfoarray;
    static ClassDeclaration* typeinfostaticarray;
    static ClassDeclaration* typeinfoassociativearray;
    static ClassDeclaration* typeinfovector;
    static ClassDeclaration* typeinfoenum;
    static ClassDeclaration* typeinfofunction;
    static ClassDeclaration* typeinfodelegate;
    static ClassDeclaration* typeinfotypelist;
    static ClassDeclaration* typeinfoconst;
    static ClassDeclaration* typeinfoinvariant;
    static ClassDeclaration* typeinfoshared;
    static ClassDeclaration* typeinfowild;
    static TemplateDeclaration* rtinfo;
    static Type* basic[46LLU];
    virtual const char* kind() const;
    Type* copy() const;
    virtual Type* syntaxCopy();
    bool equals(const RootObject* const o) const;
    bool equivalent(Type* t);
    DYNCAST dyncast() const;
    int32_t covariant(Type* t, uint64_t* pstc);
    const char* toChars() const;
    char* toPrettyChars(bool QualifyTypes = false);
    static void _init();
    static void deinitialize();
    d_uns64 size();
    virtual d_uns64 size(const Loc& loc);
    virtual uint32_t alignsize();
    Type* trySemantic(const Loc& loc, Scope* sc);
    Type* merge2();
    void modToBuffer(OutBuffer* buf) const;
    char* modToChars() const;
    virtual bool isintegral();
    virtual bool isfloating();
    virtual bool isreal();
    virtual bool isimaginary();
    virtual bool iscomplex();
    virtual bool isscalar();
    virtual bool isunsigned();
    virtual bool isscope();
    virtual bool isString();
    virtual bool isAssignable();
    virtual bool isBoolean();
    virtual void checkDeprecated(const Loc& loc, Scope* sc);
    bool isConst() const;
    bool isImmutable() const;
    bool isMutable() const;
    bool isShared() const;
    bool isSharedConst() const;
    bool isWild() const;
    bool isWildConst() const;
    bool isSharedWild() const;
    bool isNaked() const;
    Type* nullAttributes() const;
    Type* constOf();
    Type* immutableOf();
    Type* mutableOf();
    Type* sharedOf();
    Type* sharedConstOf();
    Type* unSharedOf();
    Type* wildOf();
    Type* wildConstOf();
    Type* sharedWildOf();
    Type* sharedWildConstOf();
    void fixTo(Type* t);
    void check();
    Type* addSTC(StorageClass stc);
    Type* castMod(uint8_t mod);
    Type* addMod(uint8_t mod);
    virtual Type* addStorageClass(StorageClass stc);
    Type* pointerTo();
    Type* referenceTo();
    Type* arrayOf();
    Type* sarrayOf(dinteger_t dim);
    bool hasDeprecatedAliasThis();
    Type* aliasthisOf();
    virtual Type* makeConst();
    virtual Type* makeImmutable();
    virtual Type* makeShared();
    virtual Type* makeSharedConst();
    virtual Type* makeWild();
    virtual Type* makeWildConst();
    virtual Type* makeSharedWild();
    virtual Type* makeSharedWildConst();
    virtual Type* makeMutable();
    virtual Dsymbol* toDsymbol(Scope* sc);
    Type* toBasetype();
    virtual bool isBaseOf(Type* t, int32_t* poffset);
    virtual MATCH implicitConvTo(Type* to);
    virtual MATCH constConv(Type* to);
    virtual uint8_t deduceWild(Type* t, bool isRef);
    virtual Type* substWildTo(uint32_t mod);
    Type* unqualify(uint32_t m);
    virtual Type* toHeadMutable();
    virtual ClassDeclaration* isClassHandle();
    virtual uint32_t alignment();
    virtual Expression* defaultInitLiteral(const Loc& loc);
    virtual bool isZeroInit(const Loc& loc);
    Identifier* getTypeInfoIdent();
    virtual int32_t hasWild() const;
    virtual bool hasPointers();
    virtual bool hasVoidInitPointers();
    virtual Type* nextOf();
    Type* baseElemOf();
    uint32_t numberOfElems(const Loc& loc);
    uinteger_t sizemask();
    virtual bool needsDestruction();
    virtual bool needsCopyOrPostblit();
    virtual bool needsNested();
    virtual TypeBasic* isTypeBasic();
    TypeError* isTypeError();
    TypeVector* isTypeVector();
    TypeSArray* isTypeSArray();
    TypeDArray* isTypeDArray();
    TypeAArray* isTypeAArray();
    TypePointer* isTypePointer();
    TypeReference* isTypeReference();
    TypeFunction* isTypeFunction();
    TypeDelegate* isTypeDelegate();
    TypeIdentifier* isTypeIdentifier();
    TypeInstance* isTypeInstance();
    TypeTypeof* isTypeTypeof();
    TypeReturn* isTypeReturn();
    TypeStruct* isTypeStruct();
    TypeEnum* isTypeEnum();
    TypeClass* isTypeClass();
    TypeTuple* isTypeTuple();
    TypeSlice* isTypeSlice();
    TypeNull* isTypeNull();
    TypeMixin* isTypeMixin();
    TypeTraits* isTypeTraits();
    void accept(Visitor* v);
    TypeFunction* toTypeFunction();
};

class ParseTimeVisitor
{
public:
    virtual void visit(Dsymbol* _param_0);
    virtual void visit(Parameter* _param_0);
    virtual void visit(Statement* _param_0);
    virtual void visit(Type* _param_0);
    virtual void visit(Expression* _param_0);
    virtual void visit(TemplateParameter* _param_0);
    virtual void visit(Condition* _param_0);
    virtual void visit(Initializer* _param_0);
    virtual void visit(AliasThis* s);
    virtual void visit(Declaration* s);
    virtual void visit(ScopeDsymbol* s);
    virtual void visit(Import* s);
    virtual void visit(AttribDeclaration* s);
    virtual void visit(StaticAssert* s);
    virtual void visit(DebugSymbol* s);
    virtual void visit(VersionSymbol* s);
    virtual void visit(Package* s);
    virtual void visit(EnumDeclaration* s);
    virtual void visit(AggregateDeclaration* s);
    virtual void visit(TemplateDeclaration* s);
    virtual void visit(TemplateInstance* s);
    virtual void visit(Nspace* s);
    virtual void visit(VarDeclaration* s);
    virtual void visit(FuncDeclaration* s);
    virtual void visit(AliasDeclaration* s);
    virtual void visit(TupleDeclaration* s);
    virtual void visit(FuncLiteralDeclaration* s);
    virtual void visit(PostBlitDeclaration* s);
    virtual void visit(CtorDeclaration* s);
    virtual void visit(DtorDeclaration* s);
    virtual void visit(InvariantDeclaration* s);
    virtual void visit(UnitTestDeclaration* s);
    virtual void visit(NewDeclaration* s);
    virtual void visit(StaticCtorDeclaration* s);
    virtual void visit(StaticDtorDeclaration* s);
    virtual void visit(SharedStaticCtorDeclaration* s);
    virtual void visit(SharedStaticDtorDeclaration* s);
    virtual void visit(CompileDeclaration* s);
    virtual void visit(UserAttributeDeclaration* s);
    virtual void visit(LinkDeclaration* s);
    virtual void visit(AnonDeclaration* s);
    virtual void visit(AlignDeclaration* s);
    virtual void visit(CPPMangleDeclaration* s);
    virtual void visit(CPPNamespaceDeclaration* s);
    virtual void visit(ProtDeclaration* s);
    virtual void visit(PragmaDeclaration* s);
    virtual void visit(StorageClassDeclaration* s);
    virtual void visit(ConditionalDeclaration* s);
    virtual void visit(StaticForeachDeclaration* s);
    virtual void visit(DeprecatedDeclaration* s);
    virtual void visit(StaticIfDeclaration* s);
    virtual void visit(EnumMember* s);
    virtual void visit(Module* s);
    virtual void visit(StructDeclaration* s);
    virtual void visit(UnionDeclaration* s);
    virtual void visit(ClassDeclaration* s);
    virtual void visit(InterfaceDeclaration* s);
    virtual void visit(TemplateMixin* s);
    virtual void visit(ImportStatement* s);
    virtual void visit(ScopeStatement* s);
    virtual void visit(ReturnStatement* s);
    virtual void visit(LabelStatement* s);
    virtual void visit(StaticAssertStatement* s);
    virtual void visit(CompileStatement* s);
    virtual void visit(WhileStatement* s);
    virtual void visit(ForStatement* s);
    virtual void visit(DoStatement* s);
    virtual void visit(ForeachRangeStatement* s);
    virtual void visit(ForeachStatement* s);
    virtual void visit(IfStatement* s);
    virtual void visit(ScopeGuardStatement* s);
    virtual void visit(ConditionalStatement* s);
    virtual void visit(StaticForeachStatement* s);
    virtual void visit(PragmaStatement* s);
    virtual void visit(SwitchStatement* s);
    virtual void visit(CaseRangeStatement* s);
    virtual void visit(CaseStatement* s);
    virtual void visit(DefaultStatement* s);
    virtual void visit(BreakStatement* s);
    virtual void visit(ContinueStatement* s);
    virtual void visit(GotoDefaultStatement* s);
    virtual void visit(GotoCaseStatement* s);
    virtual void visit(GotoStatement* s);
    virtual void visit(SynchronizedStatement* s);
    virtual void visit(WithStatement* s);
    virtual void visit(TryCatchStatement* s);
    virtual void visit(TryFinallyStatement* s);
    virtual void visit(ThrowStatement* s);
    virtual void visit(AsmStatement* s);
    virtual void visit(ExpStatement* s);
    virtual void visit(CompoundStatement* s);
    virtual void visit(CompoundDeclarationStatement* s);
    virtual void visit(CompoundAsmStatement* s);
    virtual void visit(InlineAsmStatement* s);
    virtual void visit(GccAsmStatement* s);
    virtual void visit(TypeBasic* t);
    virtual void visit(TypeError* t);
    virtual void visit(TypeNull* t);
    virtual void visit(TypeVector* t);
    virtual void visit(TypeEnum* t);
    virtual void visit(TypeTuple* t);
    virtual void visit(TypeClass* t);
    virtual void visit(TypeStruct* t);
    virtual void visit(TypeNext* t);
    virtual void visit(TypeQualified* t);
    virtual void visit(TypeTraits* t);
    virtual void visit(TypeMixin* t);
    virtual void visit(TypeReference* t);
    virtual void visit(TypeSlice* t);
    virtual void visit(TypeDelegate* t);
    virtual void visit(TypePointer* t);
    virtual void visit(TypeFunction* t);
    virtual void visit(TypeArray* t);
    virtual void visit(TypeDArray* t);
    virtual void visit(TypeAArray* t);
    virtual void visit(TypeSArray* t);
    virtual void visit(TypeIdentifier* t);
    virtual void visit(TypeReturn* t);
    virtual void visit(TypeTypeof* t);
    virtual void visit(TypeInstance* t);
    virtual void visit(DeclarationExp* e);
    virtual void visit(IntegerExp* e);
    virtual void visit(NewAnonClassExp* e);
    virtual void visit(IsExp* e);
    virtual void visit(RealExp* e);
    virtual void visit(NullExp* e);
    virtual void visit(TypeidExp* e);
    virtual void visit(TraitsExp* e);
    virtual void visit(StringExp* e);
    virtual void visit(NewExp* e);
    virtual void visit(AssocArrayLiteralExp* e);
    virtual void visit(ArrayLiteralExp* e);
    virtual void visit(CompileExp* e);
    virtual void visit(FuncExp* e);
    virtual void visit(IntervalExp* e);
    virtual void visit(TypeExp* e);
    virtual void visit(ScopeExp* e);
    virtual void visit(IdentifierExp* e);
    virtual void visit(UnaExp* e);
    virtual void visit(DefaultInitExp* e);
    virtual void visit(BinExp* e);
    virtual void visit(DsymbolExp* e);
    virtual void visit(TemplateExp* e);
    virtual void visit(SymbolExp* e);
    virtual void visit(TupleExp* e);
    virtual void visit(ThisExp* e);
    virtual void visit(VarExp* e);
    virtual void visit(DollarExp* e);
    virtual void visit(SuperExp* e);
    virtual void visit(AddrExp* e);
    virtual void visit(PreExp* e);
    virtual void visit(PtrExp* e);
    virtual void visit(NegExp* e);
    virtual void visit(UAddExp* e);
    virtual void visit(NotExp* e);
    virtual void visit(ComExp* e);
    virtual void visit(DeleteExp* e);
    virtual void visit(CastExp* e);
    virtual void visit(CallExp* e);
    virtual void visit(DotIdExp* e);
    virtual void visit(AssertExp* e);
    virtual void visit(ImportExp* e);
    virtual void visit(DotTemplateInstanceExp* e);
    virtual void visit(ArrayExp* e);
    virtual void visit(FuncInitExp* e);
    virtual void visit(PrettyFuncInitExp* e);
    virtual void visit(FileInitExp* e);
    virtual void visit(LineInitExp* e);
    virtual void visit(ModuleInitExp* e);
    virtual void visit(CommaExp* e);
    virtual void visit(PostExp* e);
    virtual void visit(PowExp* e);
    virtual void visit(MulExp* e);
    virtual void visit(DivExp* e);
    virtual void visit(ModExp* e);
    virtual void visit(AddExp* e);
    virtual void visit(MinExp* e);
    virtual void visit(CatExp* e);
    virtual void visit(ShlExp* e);
    virtual void visit(ShrExp* e);
    virtual void visit(UshrExp* e);
    virtual void visit(EqualExp* e);
    virtual void visit(InExp* e);
    virtual void visit(IdentityExp* e);
    virtual void visit(CmpExp* e);
    virtual void visit(AndExp* e);
    virtual void visit(XorExp* e);
    virtual void visit(OrExp* e);
    virtual void visit(LogicalExp* e);
    virtual void visit(CondExp* e);
    virtual void visit(AssignExp* e);
    virtual void visit(BinAssignExp* e);
    virtual void visit(AddAssignExp* e);
    virtual void visit(MinAssignExp* e);
    virtual void visit(MulAssignExp* e);
    virtual void visit(DivAssignExp* e);
    virtual void visit(ModAssignExp* e);
    virtual void visit(PowAssignExp* e);
    virtual void visit(AndAssignExp* e);
    virtual void visit(OrAssignExp* e);
    virtual void visit(XorAssignExp* e);
    virtual void visit(ShlAssignExp* e);
    virtual void visit(ShrAssignExp* e);
    virtual void visit(UshrAssignExp* e);
    virtual void visit(CatAssignExp* e);
    virtual void visit(TemplateAliasParameter* tp);
    virtual void visit(TemplateTypeParameter* tp);
    virtual void visit(TemplateTupleParameter* tp);
    virtual void visit(TemplateValueParameter* tp);
    virtual void visit(TemplateThisParameter* tp);
    virtual void visit(StaticIfCondition* c);
    virtual void visit(DVCondition* c);
    virtual void visit(DebugCondition* c);
    virtual void visit(VersionCondition* c);
    virtual void visit(ExpInitializer* i);
    virtual void visit(StructInitializer* i);
    virtual void visit(ArrayInitializer* i);
    virtual void visit(VoidInitializer* i);
};

class Visitor : public ParseTimeVisitor
{
public:
    virtual void visit(ErrorStatement* s);
    virtual void visit(PeelStatement* s);
    virtual void visit(UnrolledLoopStatement* s);
    virtual void visit(SwitchErrorStatement* s);
    virtual void visit(DebugStatement* s);
    virtual void visit(DtorExpStatement* s);
    virtual void visit(ForwardingStatement* s);
    virtual void visit(OverloadSet* s);
    virtual void visit(LabelDsymbol* s);
    virtual void visit(WithScopeSymbol* s);
    virtual void visit(ArrayScopeSymbol* s);
    virtual void visit(OverDeclaration* s);
    virtual void visit(SymbolDeclaration* s);
    virtual void visit(ForwardingAttribDeclaration* s);
    virtual void visit(ThisDeclaration* s);
    virtual void visit(TypeInfoDeclaration* s);
    virtual void visit(TypeInfoStructDeclaration* s);
    virtual void visit(TypeInfoClassDeclaration* s);
    virtual void visit(TypeInfoInterfaceDeclaration* s);
    virtual void visit(TypeInfoPointerDeclaration* s);
    virtual void visit(TypeInfoArrayDeclaration* s);
    virtual void visit(TypeInfoStaticArrayDeclaration* s);
    virtual void visit(TypeInfoAssociativeArrayDeclaration* s);
    virtual void visit(TypeInfoEnumDeclaration* s);
    virtual void visit(TypeInfoFunctionDeclaration* s);
    virtual void visit(TypeInfoDelegateDeclaration* s);
    virtual void visit(TypeInfoTupleDeclaration* s);
    virtual void visit(TypeInfoConstDeclaration* s);
    virtual void visit(TypeInfoInvariantDeclaration* s);
    virtual void visit(TypeInfoSharedDeclaration* s);
    virtual void visit(TypeInfoWildDeclaration* s);
    virtual void visit(TypeInfoVectorDeclaration* s);
    virtual void visit(FuncAliasDeclaration* s);
    virtual void visit(ErrorInitializer* i);
    virtual void visit(ErrorExp* e);
    virtual void visit(ComplexExp* e);
    virtual void visit(StructLiteralExp* e);
    virtual void visit(ObjcClassReferenceExp* e);
    virtual void visit(SymOffExp* e);
    virtual void visit(OverExp* e);
    virtual void visit(HaltExp* e);
    virtual void visit(DotTemplateExp* e);
    virtual void visit(DotVarExp* e);
    virtual void visit(DelegateExp* e);
    virtual void visit(DotTypeExp* e);
    virtual void visit(VectorExp* e);
    virtual void visit(VectorArrayExp* e);
    virtual void visit(SliceExp* e);
    virtual void visit(ArrayLengthExp* e);
    virtual void visit(DelegatePtrExp* e);
    virtual void visit(DelegateFuncptrExp* e);
    virtual void visit(DotExp* e);
    virtual void visit(IndexExp* e);
    virtual void visit(ConstructExp* e);
    virtual void visit(BlitExp* e);
    virtual void visit(RemoveExp* e);
    virtual void visit(ClassReferenceExp* e);
    virtual void visit(VoidInitExp* e);
    virtual void visit(ThrownExceptionExp* e);
};

class SemanticTimePermissiveVisitor : public Visitor
{
public:
    void visit(Dsymbol* _param_0);
    void visit(Parameter* _param_0);
    void visit(Statement* _param_0);
    void visit(Type* _param_0);
    void visit(Expression* _param_0);
    void visit(TemplateParameter* _param_0);
    void visit(Condition* _param_0);
    void visit(Initializer* _param_0);
};

class StatementRewriteWalker : public SemanticTimePermissiveVisitor
{
public:
    Statement** ps;
    void visitStmt(Statement*& s);
    void replaceCurrent(Statement* s);
    void visit(PeelStatement* s);
    void visit(CompoundStatement* s);
    void visit(CompoundDeclarationStatement* s);
    void visit(UnrolledLoopStatement* s);
    void visit(ScopeStatement* s);
    void visit(WhileStatement* s);
    void visit(DoStatement* s);
    void visit(ForStatement* s);
    void visit(ForeachStatement* s);
    void visit(ForeachRangeStatement* s);
    void visit(IfStatement* s);
    void visit(SwitchStatement* s);
    void visit(CaseStatement* s);
    void visit(CaseRangeStatement* s);
    void visit(DefaultStatement* s);
    void visit(SynchronizedStatement* s);
    void visit(WithStatement* s);
    void visit(TryCatchStatement* s);
    void visit(TryFinallyStatement* s);
    void visit(DebugStatement* s);
    void visit(LabelStatement* s);
};

struct ObjcFuncDeclaration
{
    ObjcSelector* selector;
    VarDeclaration* selectorParameter;
    ObjcFuncDeclaration() :
        selector(),
        selectorParameter()
    {
    }
};

struct ParameterList
{
    Array<Parameter*>* parameters;
    StorageClass stc;
    VarArg varargs;
    ParameterList(Array<Parameter*>* parameters, VarArg varargs = cast(VarArg)cast(ubyte)0u, StorageClass stc = 0);
    size_t length();
    Parameter* opIndex(size_t i);
    ParameterList() :
        parameters(),
        stc(),
        varargs((VarArg)0u)
    {
    }
};

class StoppableVisitor : public Visitor
{
public:
    bool stop;
};

struct TargetC
{
    uint32_t longsize;
    uint32_t long_doublesize;
    uint32_t criticalSectionSize;
    TargetC() :
        longsize(),
        long_doublesize(),
        criticalSectionSize()
    {
    }
};

struct TargetCPP
{
    bool reverseOverloads;
    bool exceptions;
    bool twoDtorInVtable;
    const char* toMangle(Dsymbol* s);
    const char* typeInfoMangle(ClassDeclaration* cd);
    const char* typeMangle(Type* t);
    Type* parameterType(Parameter* p);
    bool fundamentalType(const Type* const t, bool& isFundamental);
    TargetCPP() :
        reverseOverloads(),
        exceptions(),
        twoDtorInVtable()
    {
    }
};

struct TargetObjC
{
    bool supported;
    TargetObjC() :
        supported()
    {
    }
};

BEGIN_ENUM(Sizeok, SIZEOK, sizeok)
    ENUM_KEY(int32_t, none, 0, Sizeok, SIZEOK, sizeok, S)
    ENUM_KEY(int32_t, fwd, 1, Sizeok, SIZEOK, sizeok, S)
    ENUM_KEY(int32_t, inProcess, 2, Sizeok, SIZEOK, sizeok, S)
    ENUM_KEY(int32_t, done, 3, Sizeok, SIZEOK, sizeok, S)
END_ENUM(Sizeok, SIZEOK, sizeok)

BEGIN_ENUM(Baseok, BASEOK, baseok)
    ENUM_KEY(int32_t, none, 0, Baseok, BASEOK, baseok, B)
    ENUM_KEY(int32_t, start, 1, Baseok, BASEOK, baseok, B)
    ENUM_KEY(int32_t, done, 2, Baseok, BASEOK, baseok, B)
    ENUM_KEY(int32_t, semanticdone, 3, Baseok, BASEOK, baseok, B)
END_ENUM(Baseok, BASEOK, baseok)

BEGIN_ENUM(ClassKind, CLASSKIND, classkind)
    ENUM_KEY(int32_t, d, 0, ClassKind, CLASSKIND, classkind, CK)
    ENUM_KEY(int32_t, cpp, 1, ClassKind, CLASSKIND, classkind, CK)
    ENUM_KEY(int32_t, objc, 2, ClassKind, CLASSKIND, classkind, CK)
END_ENUM(ClassKind, CLASSKIND, classkind)

class AggregateDeclaration : public ScopeDsymbol
{
public:
    Type* type;
    StorageClass storage_class;
    uint32_t structsize;
    uint32_t alignsize;
    Array<VarDeclaration*> fields;
    Dsymbol* deferred;
    ClassKind classKind;
    CPPMANGLE cppmangle;
    Dsymbol* enclosing;
    VarDeclaration* vthis;
    VarDeclaration* vthis2;
    Array<FuncDeclaration*> invs;
    FuncDeclaration* inv;
    NewDeclaration* aggNew;
    Dsymbol* ctor;
    CtorDeclaration* defaultCtor;
    AliasThis* aliasthis;
    Array<DtorDeclaration*> dtors;
    DtorDeclaration* dtor;
    DtorDeclaration* primaryDtor;
    DtorDeclaration* tidtor;
    FuncDeclaration* fieldDtor;
    Expression* getRTInfo;
    Prot protection;
    bool noDefaultCtor;
    Sizeok sizeok;
    virtual Scope* newScope(Scope* sc);
    void setScope(Scope* sc);
    bool determineFields();
    size_t nonHiddenFields();
    bool determineSize(Loc loc);
    virtual void finalizeSize() = 0;
    d_uns64 size(const Loc& loc);
    bool fill(Loc loc, Array<Expression*>* elements, bool ctorinit);
    Type* getType();
    bool isDeprecated() const;
    void setDeprecated();
    bool isNested() const;
    bool isExport() const;
    Dsymbol* searchCtor();
    Prot prot();
    Type* handleType();
    Symbol* stag;
    Symbol* sinit;
    AggregateDeclaration* isAggregateDeclaration();
    void accept(Visitor* v);
    ~AggregateDeclaration();
};

class AliasThis : public Dsymbol
{
public:
    Identifier* ident;
    Dsymbol* sym;
    bool isDeprecated_;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    AliasThis* isAliasThis();
    void accept(Visitor* v);
    bool isDeprecated() const;
};

extern TypeTuple* toArgTypes_x86(Type* t);

extern TypeTuple* toArgTypes_sysv_x64(Type* t);

extern TypeTuple* toArgTypes_aarch64(Type* t);

extern bool isHFVA(Type* t, int32_t maxNumElements = 4, Type** rewriteType);

typedef Array<const char*> Strings;

typedef Array<Identifier*> Identifiers;

typedef Array<TemplateParameter*> TemplateParameters;

typedef Array<Expression*> Expressions;

typedef Array<Statement*> Statements;

typedef Array<BaseClass*> BaseClasses;

typedef Array<ClassDeclaration*> ClassDeclarations;

typedef Array<Dsymbol*> Dsymbols;

typedef Array<RootObject*> Objects;

typedef Array<DtorDeclaration*> DtorDeclarations;

typedef Array<FuncDeclaration*> FuncDeclarations;

typedef Array<Parameter*> Parameters;

typedef Array<Initializer*> Initializers;

typedef Array<VarDeclaration*> VarDeclarations;

typedef Array<Type*> Types;

typedef Array<Catch*> Catches;

typedef Array<StaticDtorDeclaration*> StaticDtorDeclarations;

typedef Array<SharedStaticDtorDeclaration*> SharedStaticDtorDeclarations;

typedef Array<AliasDeclaration*> AliasDeclarations;

typedef Array<Module*> Modules;

typedef Array<CaseStatement*> CaseStatements;

typedef Array<ScopeStatement*> ScopeStatements;

typedef Array<GotoCaseStatement*> GotoCaseStatements;

typedef Array<ReturnStatement*> ReturnStatements;

typedef Array<GotoStatement*> GotoStatements;

typedef Array<TemplateInstance*> TemplateInstances;

typedef Array<Ensure> Ensures;

class AttribDeclaration : public Dsymbol
{
public:
    Array<Dsymbol*>* decl;
    virtual Array<Dsymbol*>* include(Scope* sc);
    virtual Scope* newScope(Scope* sc);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    void setScope(Scope* sc);
    void importAll(Scope* sc);
    void addComment(const char* comment);
    const char* kind() const;
    bool oneMember(Dsymbol** ps, Identifier* ident);
    void setFieldOffset(AggregateDeclaration* ad, uint32_t* poffset, bool isunion);
    bool hasPointers();
    bool hasStaticCtorOrDtor();
    void checkCtorConstInit();
    void addLocalClass(Array<ClassDeclaration*>* aclasses);
    void addObjcSymbols(Array<ClassDeclaration*>* classes, Array<ClassDeclaration*>* categories);
    AttribDeclaration* isAttribDeclaration();
    void accept(Visitor* v);
};

class StorageClassDeclaration : public AttribDeclaration
{
public:
    StorageClass stc;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    bool oneMember(Dsymbol** ps, Identifier* ident);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    StorageClassDeclaration* isStorageClassDeclaration();
    void accept(Visitor* v);
};

class DeprecatedDeclaration : public StorageClassDeclaration
{
public:
    Expression* msg;
    char* msgstr;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    void setScope(Scope* sc);
    void accept(Visitor* v);
};

class LinkDeclaration : public AttribDeclaration
{
public:
    LINK linkage;
    static LinkDeclaration* create(LINK p, Array<Dsymbol*>* decl);
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    const char* toChars() const;
    void accept(Visitor* v);
};

class CPPMangleDeclaration : public AttribDeclaration
{
public:
    CPPMANGLE cppmangle;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    void setScope(Scope* sc);
    const char* toChars() const;
    void accept(Visitor* v);
};

class CPPNamespaceDeclaration : public AttribDeclaration
{
public:
    Expression* exp;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    const char* toChars() const;
    void accept(Visitor* v);
    CPPNamespaceDeclaration* isCPPNamespaceDeclaration();
};

class ProtDeclaration : public AttribDeclaration
{
public:
    Prot protection;
    Array<Identifier*>* pkg_identifiers;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    const char* kind() const;
    const char* toPrettyChars(bool _param_0);
    ProtDeclaration* isProtDeclaration();
    void accept(Visitor* v);
};

class AlignDeclaration : public AttribDeclaration
{
public:
    Expression* ealign;
    ENUM_CONSTANT_NUMERIC(uint32_t, UNKNOWN, 0u)

    uint32_t salign;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    void accept(Visitor* v);
};

class AnonDeclaration : public AttribDeclaration
{
public:
    bool isunion;
    int32_t sem;
    uint32_t anonoffset;
    uint32_t anonstructsize;
    uint32_t anonalignsize;
    Dsymbol* syntaxCopy(Dsymbol* s);
    void setScope(Scope* sc);
    void setFieldOffset(AggregateDeclaration* ad, uint32_t* poffset, bool isunion);
    const char* kind() const;
    AnonDeclaration* isAnonDeclaration();
    void accept(Visitor* v);
};

class PragmaDeclaration : public AttribDeclaration
{
public:
    Array<Expression*>* args;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    const char* kind() const;
    void accept(Visitor* v);
};

class ConditionalDeclaration : public AttribDeclaration
{
public:
    Condition* condition;
    Array<Dsymbol*>* elsedecl;
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool oneMember(Dsymbol** ps, Identifier* ident);
    Array<Dsymbol*>* include(Scope* sc);
    void addComment(const char* comment);
    void setScope(Scope* sc);
    void accept(Visitor* v);
};

class StaticIfDeclaration : public ConditionalDeclaration
{
public:
    ScopeDsymbol* scopesym;
    bool addisdone;
    bool onStack;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Array<Dsymbol*>* include(Scope* sc);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    void setScope(Scope* sc);
    void importAll(Scope* sc);
    const char* kind() const;
    void accept(Visitor* v);
};

class StaticForeachDeclaration : public AttribDeclaration
{
public:
    StaticForeach* sfe;
    ScopeDsymbol* scopesym;
    bool onStack;
    bool cached;
    Array<Dsymbol*>* cache;
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool oneMember(Dsymbol** ps, Identifier* ident);
    Array<Dsymbol*>* include(Scope* sc);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    void addComment(const char* comment);
    void setScope(Scope* sc);
    void importAll(Scope* sc);
    const char* kind() const;
    void accept(Visitor* v);
};

class ForwardingAttribDeclaration : public AttribDeclaration
{
public:
    ForwardingScopeDsymbol* sym;
    ForwardingAttribDeclaration(Array<Dsymbol*>* decl);
    Scope* newScope(Scope* sc);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    ForwardingAttribDeclaration* isForwardingAttribDeclaration();
    void accept(Visitor* v);
};

class CompileDeclaration : public AttribDeclaration
{
public:
    Array<Expression*>* exps;
    ScopeDsymbol* scopesym;
    bool compiled;
    Dsymbol* syntaxCopy(Dsymbol* s);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    void setScope(Scope* sc);
    const char* kind() const;
    CompileDeclaration* isCompileDeclaration();
    void accept(Visitor* v);
};

class UserAttributeDeclaration : public AttribDeclaration
{
public:
    Array<Expression*>* atts;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    void setScope(Scope* sc);
    Array<Expression*>* getAttributes();
    const char* kind() const;
    void accept(Visitor* v);
    static bool isGNUABITag(Expression* e);
    static void checkGNUABITag(Dsymbol* sym, LINK linkage);
};

BEGIN_ENUM(BE, BE, be)
    ENUM_KEY(int32_t, none, 0, BE, BE, be, BE)
    ENUM_KEY(int32_t, fallthru, 1, BE, BE, be, BE)
    ENUM_KEY(int32_t, throw_, 2, BE, BE, be, BE)
    ENUM_KEY(int32_t, return_, 4, BE, BE, be, BE)
    ENUM_KEY(int32_t, goto_, 8, BE, BE, be, BE)
    ENUM_KEY(int32_t, halt, 16, BE, BE, be, BE)
    ENUM_KEY(int32_t, break_, 32, BE, BE, be, BE)
    ENUM_KEY(int32_t, continue_, 64, BE, BE, be, BE)
    ENUM_KEY(int32_t, errthrow, 128, BE, BE, be, BE)
    ENUM_KEY(int32_t, any, 31, BE, BE, be, BE)
END_ENUM(BE, BE, be)

extern BUILTIN isBuiltin(FuncDeclaration* fd);

extern Expression* eval_builtin(Loc loc, FuncDeclaration* fd, Array<Expression*>* arguments);

extern bool canThrow(Expression* e, FuncDeclaration* func, bool mustNotThrow);

BEGIN_ENUM(TargetOS, TARGETOS, targetos)
    ENUM_KEY(int32_t, all, 2147483647, TargetOS, TARGETOS, targetos, TOS)
    ENUM_KEY(int32_t, linux, 1, TargetOS, TARGETOS, targetos, TOS)
    ENUM_KEY(int32_t, windows, 2, TargetOS, TARGETOS, targetos, TOS)
    ENUM_KEY(int32_t, macOS, 4, TargetOS, TARGETOS, targetos, TOS)
    ENUM_KEY(int32_t, freeBSD, 8, TargetOS, TARGETOS, targetos, TOS)
    ENUM_KEY(int32_t, solaris, 16, TargetOS, TARGETOS, targetos, TOS)
    ENUM_KEY(int32_t, dragonFlyBSD, 32, TargetOS, TARGETOS, targetos, TOS)
END_ENUM(TargetOS, TARGETOS, targetos)

extern Module* rootHasMain;

extern bool includeImports;

extern Array<const char*> includeModulePatterns;

extern Array<Module*> compiledImports;

struct Compiler
{
    static Expression* paintAsType(UnionExp* pue, Expression* e, Type* type);
    static void onParseModule(Module* m);
    static bool onImport(Module* m);
    Compiler()
    {
    }
};

struct complex_t
{
    _d_real re;
    _d_real im;
    private: complex_t();
    public:
    complex_t(_d_real re);
    complex_t(_d_real re, _d_real im);
    int32_t opEquals(complex_t y) const;
};

extern _d_real creall(complex_t x);

extern _d_real cimagl(complex_t x);

BEGIN_ENUM(Include, INCLUDE, include)
    ENUM_KEY(int32_t, notComputed, 0, Include, INCLUDE, include, I)
    ENUM_KEY(int32_t, yes, 1, Include, INCLUDE, include, I)
    ENUM_KEY(int32_t, no, 2, Include, INCLUDE, include, I)
END_ENUM(Include, INCLUDE, include)

class Condition : public ASTNode
{
public:
    Loc loc;
    Include inc;
    DYNCAST dyncast() const;
    virtual Condition* syntaxCopy() = 0;
    virtual int32_t include(Scope* sc) = 0;
    virtual DebugCondition* isDebugCondition();
    virtual VersionCondition* isVersionCondition();
    void accept(Visitor* v);
};

class StaticForeach : public RootObject
{
public:
    Loc loc;
    ForeachStatement* aggrfe;
    ForeachRangeStatement* rangefe;
    bool needExpansion;
    StaticForeach* syntaxCopy();
    void lowerNonArrayAggregate(Scope* sc);
};

class DVCondition : public Condition
{
public:
    uint32_t level;
    Identifier* ident;
    Module* mod;
    Condition* syntaxCopy();
    void accept(Visitor* v);
};

class DebugCondition : public DVCondition
{
public:
    static void addGlobalIdent(const char* ident);
    int32_t include(Scope* sc);
    DebugCondition* isDebugCondition();
    void accept(Visitor* v);
    const char* toChars() const;
};

class VersionCondition : public DVCondition
{
public:
    static void addGlobalIdent(const char* ident);
    static void addPredefinedGlobalIdent(const char* ident);
    int32_t include(Scope* sc);
    VersionCondition* isVersionCondition();
    void accept(Visitor* v);
    const char* toChars() const;
};

class StaticIfCondition : public Condition
{
public:
    Expression* exp;
    Condition* syntaxCopy();
    int32_t include(Scope* sc);
    void accept(Visitor* v);
    const char* toChars() const;
};

BEGIN_ENUM(CppOperator, CPPOPERATOR, cppoperator)
    ENUM_KEY(int32_t, Cast, 0, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, Assign, 1, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, Eq, 2, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, Index, 3, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, Call, 4, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, Unary, 5, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, Binary, 6, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, OpAssign, 7, CppOperator, CPPOPERATOR, cppoperator, CO)
    ENUM_KEY(int32_t, Unknown, 8, CppOperator, CPPOPERATOR, cppoperator, CO)
END_ENUM(CppOperator, CPPOPERATOR, cppoperator)

extern const char* toCppMangleItanium(Dsymbol* s);

extern const char* cppTypeInfoMangleItanium(Dsymbol* s);

extern const char* toCppMangleMSVC(Dsymbol* s);

extern const char* cppTypeInfoMangleMSVC(Dsymbol* s);

class ClassReferenceExp : public Expression
{
public:
    StructLiteralExp* value;
    ClassDeclaration* originalClass();
    int32_t getFieldIndex(Type* fieldtype, uint32_t fieldoffset);
    int32_t findFieldIndexByName(VarDeclaration* v);
    void accept(Visitor* v);
};

class ThrownExceptionExp : public Expression
{
public:
    ClassReferenceExp* thrown;
    const char* toChars() const;
    void accept(Visitor* v);
};

class CTFEExp : public Expression
{
public:
    const char* toChars() const;
};

BEGIN_ENUM_NUMERIC(uint16_t, CSX, CSX, csx)
    ENUM_KEY_NUMERIC(uint16_t, none, 0u, CSX, CSX, csx, CSX)
    ENUM_KEY_NUMERIC(uint16_t, this_ctor, 1u, CSX, CSX, csx, CSX)
    ENUM_KEY_NUMERIC(uint16_t, super_ctor, 2u, CSX, CSX, csx, CSX)
    ENUM_KEY_NUMERIC(uint16_t, label, 4u, CSX, CSX, csx, CSX)
    ENUM_KEY_NUMERIC(uint16_t, return_, 8u, CSX, CSX, csx, CSX)
    ENUM_KEY_NUMERIC(uint16_t, any_ctor, 16u, CSX, CSX, csx, CSX)
    ENUM_KEY_NUMERIC(uint16_t, halt, 32u, CSX, CSX, csx, CSX)
END_ENUM_NUMERIC(uint16_t, CSX, CSX, csx)

ENUM_CONSTANT_NUMERIC(bool, LOG, false)

extern bool arrayTypeCompatibleWithoutCasting(Type* t1, Type* t2);

BEGIN_ENUM(Abstract, ABSTRACT, abstract)
    ENUM_KEY(int32_t, fwdref, 0, Abstract, ABSTRACT, abstract, A)
    ENUM_KEY(int32_t, yes, 1, Abstract, ABSTRACT, abstract, A)
    ENUM_KEY(int32_t, no, 2, Abstract, ABSTRACT, abstract, A)
END_ENUM(Abstract, ABSTRACT, abstract)

struct BaseClass
{
    Type* type;
    ClassDeclaration* sym;
    uint32_t offset;
    Array<FuncDeclaration*> vtbl;
    DArray< BaseClass > baseInterfaces;
    bool fillVtbl(ClassDeclaration* cd, Array<FuncDeclaration*>* vtbl, int32_t newinstance);
    ~BaseClass();
    BaseClass() :
        type(),
        sym(),
        offset(),
        vtbl(),
        baseInterfaces()
    {
    }
};

BEGIN_ENUM(ClassFlags, CLASSFLAGS, classflags)
    ENUM_KEY(int32_t, none, 0, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, isCOMclass, 1, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, noPointers, 2, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, hasOffTi, 4, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, hasCtor, 8, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, hasGetMembers, 16, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, hasTypeInfo, 32, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, isAbstract, 64, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, isCPPclass, 128, ClassFlags, CLASSFLAGS, classflags, CF)
    ENUM_KEY(int32_t, hasDtor, 256, ClassFlags, CLASSFLAGS, classflags, CF)
END_ENUM(ClassFlags, CLASSFLAGS, classflags)

class ClassDeclaration : public AggregateDeclaration
{
public:
    static ClassDeclaration* object;
    static ClassDeclaration* throwable;
    static ClassDeclaration* exception;
    static ClassDeclaration* errorException;
    static ClassDeclaration* cpp_type_info_ptr;
    ClassDeclaration* baseClass;
    FuncDeclaration* staticCtor;
    FuncDeclaration* staticDtor;
    Array<Dsymbol*> vtbl;
    Array<Dsymbol*> vtblFinal;
    Array<BaseClass*>* baseclasses;
    DArray< BaseClass* > interfaces;
    Array<BaseClass*>* vtblInterfaces;
    TypeInfoClassDeclaration* vclassinfo;
    bool com;
    bool stack;
    int32_t cppDtorVtblIndex;
    bool inuse;
    Abstract isabstract;
    Baseok baseok;
    ObjcClassDeclaration objc;
    Symbol* cpp_type_info_ptr_sym;
    static ClassDeclaration* create(Loc loc, Identifier* id, Array<BaseClass*>* baseclasses, Array<Dsymbol*>* members, bool inObject);
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    bool isBaseOf2(ClassDeclaration* cd);
    ENUM_CONSTANT_NUMERIC(int32_t, OFFSET_RUNTIME, 1985229328)

    ENUM_CONSTANT_NUMERIC(int32_t, OFFSET_FWDREF, 1985229329)

    virtual bool isBaseOf(ClassDeclaration* cd, int32_t* poffset);
    bool isBaseInfoComplete() const;
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    ClassDeclaration* searchBase(Identifier* ident);
    void finalizeSize();
    bool hasMonitor();
    bool isFuncHidden(FuncDeclaration* fd);
    FuncDeclaration* findFunc(Identifier* ident, TypeFunction* tf);
    bool isCOMclass() const;
    virtual bool isCOMinterface() const;
    bool isCPPclass() const;
    virtual bool isCPPinterface() const;
    bool isAbstract();
    virtual int32_t vtblOffset() const;
    const char* kind() const;
    void addLocalClass(Array<ClassDeclaration*>* aclasses);
    void addObjcSymbols(Array<ClassDeclaration*>* classes, Array<ClassDeclaration*>* categories);
    Dsymbol* vtblsym;
    Dsymbol* vtblSymbol();
    ClassDeclaration* isClassDeclaration();
    void accept(Visitor* v);
    ~ClassDeclaration();
};

class InterfaceDeclaration : public ClassDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    bool isBaseOf(ClassDeclaration* cd, int32_t* poffset);
    bool isBaseOf(BaseClass* bc, int32_t* poffset);
    const char* kind() const;
    int32_t vtblOffset() const;
    bool isCPPinterface() const;
    bool isCOMinterface() const;
    InterfaceDeclaration* isInterfaceDeclaration();
    void accept(Visitor* v);
    ~InterfaceDeclaration();
};

extern void ObjectNotFound(Identifier* id);

BEGIN_ENUM_NUMERIC(uint64_t, STC, STC, stc)
    ENUM_KEY_NUMERIC(uint64_t, undefined_, 0LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, static_, 1LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, extern_, 2LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, const_, 4LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, final_, 8LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, abstract_, 16LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, parameter, 32LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, field, 64LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, override_, 128LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, auto_, 256LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, synchronized_, 512LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, deprecated_, 1024LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, in_, 2048LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, out_, 4096LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, lazy_, 8192LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, foreach_, 16384LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, variadic, 65536LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, ctorinit, 131072LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, templateparameter, 262144LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, scope_, 524288LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, immutable_, 1048576LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, ref_, 2097152LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, init, 4194304LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, manifest, 8388608LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, nodtor, 16777216LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, nothrow_, 33554432LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, pure_, 67108864LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, tls, 134217728LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, alias_, 268435456LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, shared_, 536870912LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, gshared, 1073741824LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, wild, 2147483648LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, property, 4294967296LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, safe, 8589934592LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, trusted, 17179869184LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, system, 34359738368LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, ctfe, 68719476736LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, disable, 137438953472LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, result, 274877906944LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, nodefaultctor, 549755813888LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, temp, 1099511627776LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, rvalue, 2199023255552LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, nogc, 4398046511104LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, volatile_, 8796093022208LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, return_, 17592186044416LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, autoref, 35184372088832LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, inference, 70368744177664LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, exptemp, 140737488355328LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, maybescope, 281474976710656LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, scopeinferred, 562949953421312LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, future, 1125899906842624LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, local, 2251799813685248LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, returninferred, 4503599627370496LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, live, 9007199254740992LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, safeGroup, 60129542144LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, IOR, 2103296LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, TYPECTOR, 2685403140LLU, STC, STC, stc, STC)
    ENUM_KEY_NUMERIC(uint64_t, FUNCATTR, 9011661828521984LLU, STC, STC, stc, STC)
END_ENUM_NUMERIC(uint64_t, STC, STC, stc)

ENUM_CONSTANT(STC, STCStorageClass, (STC)12407095344775071LLU)

ENUM_CONSTANT(STC, STCFlowThruAggregate, (STC)60129542144LLU)

ENUM_CONSTANT(STC, STCFlowThruFunction, (STC)18446726413102348896LLU)

class Declaration : public Dsymbol
{
public:
    Type* type;
    Type* originalType;
    StorageClass storage_class;
    Prot protection;
    LINK linkage;
    int32_t inuse;
    DArray< char > mangleOverride;
    const char* kind() const;
    d_uns64 size(const Loc& loc);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    bool isStatic() const;
    virtual bool isDelete();
    virtual bool isDataseg();
    virtual bool isThreadlocal();
    virtual bool isCodeseg() const;
    bool isCtorinit() const;
    bool isFinal() const;
    virtual bool isAbstract();
    bool isConst() const;
    bool isImmutable() const;
    bool isWild() const;
    bool isAuto() const;
    bool isScope() const;
    bool isSynchronized() const;
    bool isParameter() const;
    bool isDeprecated() const;
    bool isDisabled() const;
    bool isOverride() const;
    bool isResult() const;
    bool isField() const;
    bool isIn() const;
    bool isOut() const;
    bool isRef() const;
    bool isFuture() const;
    Prot prot();
    Declaration* isDeclaration();
    void accept(Visitor* v);
};

class TupleDeclaration : public Declaration
{
public:
    Array<RootObject*>* objects;
    bool isexp;
    TypeTuple* tupletype;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    Type* getType();
    Dsymbol* toAlias2();
    bool needThis();
    TupleDeclaration* isTupleDeclaration();
    void accept(Visitor* v);
};

class AliasDeclaration : public Declaration
{
public:
    Dsymbol* aliassym;
    Dsymbol* overnext;
    Dsymbol* _import;
    static AliasDeclaration* create(Loc loc, Identifier* id, Type* type);
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool overloadInsert(Dsymbol* s);
    const char* kind() const;
    Type* getType();
    Dsymbol* toAlias();
    Dsymbol* toAlias2();
    bool isOverloadable() const;
    AliasDeclaration* isAliasDeclaration();
    void accept(Visitor* v);
};

class OverDeclaration : public Declaration
{
public:
    Dsymbol* overnext;
    Dsymbol* aliassym;
    bool hasOverloads;
    const char* kind() const;
    bool equals(const RootObject* const o) const;
    bool overloadInsert(Dsymbol* s);
    bool isOverloadable() const;
    Dsymbol* isUnique();
    OverDeclaration* isOverDeclaration();
    void accept(Visitor* v);
};

class VarDeclaration : public Declaration
{
public:
    Initializer* _init;
    uint32_t offset;
    uint32_t sequenceNumber;
    static uint32_t nextSequenceNumber;
    Array<FuncDeclaration*> nestedrefs;
    uint32_t alignment;
    bool isargptr;
    bool ctorinit;
    bool iscatchvar;
    bool isowner;
    bool onstack;
    bool mynew;
    int8_t canassign;
    bool overlapped;
    bool overlapUnsafe;
    bool doNotInferScope;
    bool doNotInferReturn;
    uint8_t isdataseg;
    Dsymbol* aliassym;
    VarDeclaration* lastVar;
    uint32_t endlinnum;
    ENUM_CONSTANT_NUMERIC(uint32_t, AdrOnStackNone, 4294967295u)

    uint32_t ctfeAdrOnStack;
    Expression* edtor;
    IntRange* range;
    Array<VarDeclaration*>* maybes;
    static VarDeclaration* create(const Loc& loc, Type* type, Identifier* ident, Initializer* _init, StorageClass storage_class);
    Dsymbol* syntaxCopy(Dsymbol* s);
    void setFieldOffset(AggregateDeclaration* ad, uint32_t* poffset, bool isunion);
    const char* kind() const;
    AggregateDeclaration* isThis();
    bool needThis();
    bool isExport() const;
    bool isImportedSymbol() const;
    bool isDataseg();
    bool isThreadlocal();
    bool isCTFE();
    bool isOverlappedWith(VarDeclaration* v);
    bool hasPointers();
    bool canTakeAddressOf();
    bool needsScopeDtor();
    void checkCtorConstInit();
    Dsymbol* toAlias();
    VarDeclaration* isVarDeclaration();
    void accept(Visitor* v);
    bool enclosesLifetimeOf(VarDeclaration* v) const;
    void addMaybe(VarDeclaration* v);
    ~VarDeclaration();
};

class SymbolDeclaration : public Declaration
{
public:
    StructDeclaration* dsym;
    SymbolDeclaration* isSymbolDeclaration();
    void accept(Visitor* v);
};

class TypeInfoDeclaration : public VarDeclaration
{
public:
    Type* tinfo;
    static TypeInfoDeclaration* create(Type* tinfo);
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* toChars() const;
    TypeInfoDeclaration* isTypeInfoDeclaration();
    void accept(Visitor* v);
    ~TypeInfoDeclaration();
};

class TypeInfoStructDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoStructDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoStructDeclaration();
};

class TypeInfoClassDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoClassDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoClassDeclaration();
};

class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoInterfaceDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoInterfaceDeclaration();
};

class TypeInfoPointerDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoPointerDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoPointerDeclaration();
};

class TypeInfoArrayDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoArrayDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoArrayDeclaration();
};

class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoStaticArrayDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoStaticArrayDeclaration();
};

class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoAssociativeArrayDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoAssociativeArrayDeclaration();
};

class TypeInfoEnumDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoEnumDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoEnumDeclaration();
};

class TypeInfoFunctionDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoFunctionDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoFunctionDeclaration();
};

class TypeInfoDelegateDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoDelegateDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoDelegateDeclaration();
};

class TypeInfoTupleDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoTupleDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoTupleDeclaration();
};

class TypeInfoConstDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoConstDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoConstDeclaration();
};

class TypeInfoInvariantDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoInvariantDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoInvariantDeclaration();
};

class TypeInfoSharedDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoSharedDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoSharedDeclaration();
};

class TypeInfoWildDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoWildDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoWildDeclaration();
};

class TypeInfoVectorDeclaration : public TypeInfoDeclaration
{
public:
    static TypeInfoVectorDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoVectorDeclaration();
};

class ThisDeclaration : public VarDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    ThisDeclaration* isThisDeclaration();
    void accept(Visitor* v);
    ~ThisDeclaration();
};

class EnumDeclaration : public ScopeDsymbol
{
public:
    Type* type;
    Type* memtype;
    Prot protection;
    Expression* maxval;
    Expression* minval;
    Expression* defaultval;
    bool isdeprecated;
    bool added;
    int32_t inuse;
    Dsymbol* syntaxCopy(Dsymbol* s);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    void setScope(Scope* sc);
    bool oneMember(Dsymbol** ps, Identifier* ident);
    Type* getType();
    const char* kind() const;
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    bool isDeprecated() const;
    Prot prot();
    Expression* getMaxMinValue(const Loc& loc, Identifier* id);
    bool isSpecial() const;
    Expression* getDefaultValue(const Loc& loc);
    Type* getMemtype(const Loc& loc);
    EnumDeclaration* isEnumDeclaration();
    Symbol* sinit;
    void accept(Visitor* v);
    ~EnumDeclaration();
};

class EnumMember : public VarDeclaration
{
public:
    Expression*& value();
    Expression* origValue;
    Type* origType;
    EnumDeclaration* ed;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    Expression* getVarExp(const Loc& loc, Scope* sc);
    EnumMember* isEnumMember();
    void accept(Visitor* v);
    ~EnumMember();
};

class Import : public Dsymbol
{
public:
    Array<Identifier*>* packages;
    Identifier* id;
    Identifier* aliasId;
    int32_t isstatic;
    Prot protection;
    Array<Identifier*> names;
    Array<Identifier*> aliases;
    Module* mod;
    Package* pkg;
    Array<AliasDeclaration*> aliasdecls;
    const char* kind() const;
    Prot prot();
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool load(Scope* sc);
    void importAll(Scope* sc);
    Dsymbol* toAlias();
    void addMember(Scope* sc, ScopeDsymbol* sd);
    void setScope(Scope* sc);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    bool overloadInsert(Dsymbol* s);
    Import* isImport();
    void accept(Visitor* v);
    ~Import();
};

extern Expression* getValue(VarDeclaration* vd);

extern void printCtfePerformanceStats();

struct MacroTable
{
    Macro* mactab;
    MacroTable()
    {
    }
};

extern const char* mangleExact(FuncDeclaration* fd);

extern void mangleToBuffer(Type* t, OutBuffer* buf);

extern void mangleToBuffer(Expression* e, OutBuffer* buf);

extern void mangleToBuffer(Dsymbol* s, OutBuffer* buf);

extern void mangleToBuffer(TemplateInstance* ti, OutBuffer* buf);

BEGIN_ENUM(PKG, PKG, pkg)
    ENUM_KEY(int32_t, unknown, 0, PKG, PKG, pkg, PKG)
    ENUM_KEY(int32_t, module_, 1, PKG, PKG, pkg, PKG)
    ENUM_KEY(int32_t, package_, 2, PKG, PKG, pkg, PKG)
END_ENUM(PKG, PKG, pkg)

class Package : public ScopeDsymbol
{
public:
    PKG isPkgMod;
    uint32_t tag;
    Module* mod;
    const char* kind() const;
    bool equals(const RootObject* const o) const;
    Package* isPackage();
    bool isAncestorPackageOf(const Package* const pkg) const;
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    void accept(Visitor* v);
    Module* isPackageMod();
    void resolvePKGunknown();
    ~Package();
};

class Module : public Package
{
public:
    static Module* rootModule;
    static DsymbolTable* modules;
    static Array<Module*> amodules;
    static Array<Dsymbol*> deferred;
    static Array<Dsymbol*> deferred2;
    static Array<Dsymbol*> deferred3;
    static uint32_t dprogress;
    static void _init();
    static void deinitialize();
    static AggregateDeclaration* moduleinfo;
    DArray< char > arg;
    ModuleDeclaration* md;
    FileName srcfile;
    FileName objfile;
    FileName hdrfile;
    FileName docfile;
    FileBuffer* srcBuffer;
    uint32_t errors;
    uint32_t numlines;
    bool isHdrFile;
    bool isDocFile;
    bool hasAlwaysInlines;
    bool isPackageFile;
    Package* pkg;
    Array<char*> contentImportedFiles;
    int32_t needmoduleinfo;
    int32_t selfimports;
    bool selfImports();
    int32_t rootimports;
    bool rootImports();
    int32_t insearch;
    Identifier* searchCacheIdent;
    Dsymbol* searchCacheSymbol;
    int32_t searchCacheFlags;
    Module* importedFrom;
    Array<Dsymbol*>* decldefs;
    Array<Module*> aimports;
    uint32_t debuglevel;
    Array<Identifier*>* debugids;
    Array<Identifier*>* debugidsNot;
    uint32_t versionlevel;
    Array<Identifier*>* versionids;
    Array<Identifier*>* versionidsNot;
    MacroTable macrotable;
    Escape* escapetable;
    size_t nameoffset;
    size_t namelen;
    static Module* create(const char* filename, Identifier* ident, int32_t doDocComment, int32_t doHdrGen);
    static Module* load(Loc loc, Array<Identifier*>* packages, Identifier* ident);
    const char* kind() const;
    bool loadSourceBuffer(const Loc& loc, ReadResult& readResult);
    bool read(const Loc& loc);
    Module* parse();
    void importAll(Scope* prevsc);
    int32_t needModuleInfo();
    void checkImportDeprecation(const Loc& loc, Scope* sc);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    bool isPackageAccessible(Package* p, Prot protection, int32_t flags = 0);
    Dsymbol* symtabInsert(Dsymbol* s);
    void deleteObjFile();
    static void runDeferredSemantic();
    static void runDeferredSemantic2();
    static void runDeferredSemantic3();
    int32_t imports(Module* m);
    bool isRoot();
    bool isCoreModule(Identifier* ident);
    int32_t doppelganger;
    Symbol* cov;
    uint32_t* covb;
    Symbol* sictor;
    Symbol* sctor;
    Symbol* sdtor;
    Symbol* ssharedctor;
    Symbol* sshareddtor;
    Symbol* stest;
    Symbol* sfilename;
    void* ctfe_cov;
    Module* isModule();
    void accept(Visitor* v);
    void fullyQualifiedName(OutBuffer& buf);
    ~Module();
};

struct ModuleDeclaration
{
    Loc loc;
    Identifier* id;
    Array<Identifier*>* packages;
    bool isdeprecated;
    Expression* msg;
    const char* toChars() const;
    ModuleDeclaration() :
        loc(),
        id(),
        packages(),
        isdeprecated(),
        msg()
    {
    }
};

extern void gendocfile(Module* m);

BEGIN_ENUM(SCOPE, SCOPE, scope)
    ENUM_KEY(int32_t, ctor, 1, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, noaccesscheck, 2, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, condition, 4, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, debug_, 8, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, constraint, 16, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, invariant_, 32, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, require, 64, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, ensure, 96, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, contract, 96, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, ctfe, 128, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, compile, 256, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, ignoresymbolvisibility, 512, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, onlysafeaccess, 1024, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, free, 32768, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, fullinst, 65536, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, alias_, 131072, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, printf, 262144, SCOPE, SCOPE, scope, SCOPE)
    ENUM_KEY(int32_t, scanf, 524288, SCOPE, SCOPE, scope, SCOPE)
END_ENUM(SCOPE, SCOPE, scope)

ENUM_CONSTANT(SCOPE, SCOPEpush, (SCOPE)788474)

extern FuncDeclaration* search_toString(StructDeclaration* sd);

extern void semanticTypeInfo(Scope* sc, Type* t);

BEGIN_ENUM(StructFlags, STRUCTFLAGS, structflags)
    ENUM_KEY(int32_t, none, 0, StructFlags, STRUCTFLAGS, structflags, SF)
    ENUM_KEY(int32_t, hasPointers, 1, StructFlags, STRUCTFLAGS, structflags, SF)
END_ENUM(StructFlags, STRUCTFLAGS, structflags)

BEGIN_ENUM(StructPOD, STRUCTPOD, structpod)
    ENUM_KEY(int32_t, no, 0, StructPOD, STRUCTPOD, structpod, SPOD)
    ENUM_KEY(int32_t, yes, 1, StructPOD, STRUCTPOD, structpod, SPOD)
    ENUM_KEY(int32_t, fwd, 2, StructPOD, STRUCTPOD, structpod, SPOD)
END_ENUM(StructPOD, STRUCTPOD, structpod)

class StructDeclaration : public AggregateDeclaration
{
public:
    bool zeroInit;
    bool hasIdentityAssign;
    bool hasBlitAssign;
    bool hasIdentityEquals;
    bool hasNoFields;
    bool hasCopyCtor;
    bool requestTypeInfo;
    Array<FuncDeclaration*> postblits;
    FuncDeclaration* postblit;
    FuncDeclaration* xeq;
    FuncDeclaration* xcmp;
    FuncDeclaration* xhash;
    static FuncDeclaration* xerreq;
    static FuncDeclaration* xerrcmp;
    uint32_t alignment;
    StructPOD ispod;
    TypeTuple* argTypes;
    static StructDeclaration* create(Loc loc, Identifier* id, bool inObject);
    Dsymbol* syntaxCopy(Dsymbol* s);
    void semanticTypeInfoMembers();
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    const char* kind() const;
    void finalizeSize();
    bool fit(const Loc& loc, Scope* sc, Array<Expression*>* elements, Type* stype);
    bool isPOD();
    StructDeclaration* isStructDeclaration();
    void accept(Visitor* v);
    uint32_t numArgTypes() const;
    Type* argType(uint32_t index);
    bool hasNonDisabledCtor();
    ~StructDeclaration();
};

class UnionDeclaration : public StructDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    UnionDeclaration* isUnionDeclaration();
    void accept(Visitor* v);
    ~UnionDeclaration();
};

BEGIN_ANON_ENUM()
    ANON_ENUM_KEY(int32_t, IgnoreNone, 0)
    ANON_ENUM_KEY(int32_t, IgnorePrivateImports, 1)
    ANON_ENUM_KEY(int32_t, IgnoreErrors, 2)
    ANON_ENUM_KEY(int32_t, IgnoreAmbiguous, 4)
    ANON_ENUM_KEY(int32_t, SearchLocalsOnly, 8)
    ANON_ENUM_KEY(int32_t, SearchImportsOnly, 16)
    ANON_ENUM_KEY(int32_t, SearchUnqualifiedModule, 32)
    ANON_ENUM_KEY(int32_t, IgnoreSymbolVisibility, 128)
END_ANON_ENUM()

class WithScopeSymbol : public ScopeDsymbol
{
public:
    WithStatement* withstate;
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    WithScopeSymbol* isWithScopeSymbol();
    void accept(Visitor* v);
    ~WithScopeSymbol();
};

class ArrayScopeSymbol : public ScopeDsymbol
{
public:
    RootObject* arrayContent;
    Scope* sc;
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 0);
    ArrayScopeSymbol* isArrayScopeSymbol();
    void accept(Visitor* v);
    ~ArrayScopeSymbol();
};

class OverloadSet : public Dsymbol
{
public:
    Array<Dsymbol*> a;
    void push(Dsymbol* s);
    OverloadSet* isOverloadSet();
    const char* kind() const;
    void accept(Visitor* v);
    ~OverloadSet();
};

class ForwardingScopeDsymbol : public ScopeDsymbol
{
public:
    ScopeDsymbol* forward;
    Dsymbol* symtabInsert(Dsymbol* s);
    Dsymbol* symtabLookup(Dsymbol* s, Identifier* id);
    void importScope(Dsymbol* s, Prot protection);
    const char* kind() const;
    ForwardingScopeDsymbol* isForwardingScopeDsymbol();
    ~ForwardingScopeDsymbol();
};

class ExpressionDsymbol : public Dsymbol
{
public:
    Expression* exp;
    ExpressionDsymbol(Expression* exp);
    ExpressionDsymbol* isExpressionDsymbol();
};

class DsymbolTable : public RootObject
{
public:
    AssocArray<Identifier*, Dsymbol*> tab;
    Dsymbol* lookup(const Identifier* const ident);
    Dsymbol* update(Dsymbol* s);
    Dsymbol* insert(Dsymbol* s);
    Dsymbol* insert(const Identifier* const ident, Dsymbol* s);
    size_t length() const;
    DsymbolTable();
};

ENUM_CONSTANT_NUMERIC(bool, LOG, false)

extern void dsymbolSemantic(Dsymbol* dsym, Scope* sc);

ENUM_CONSTANT_NUMERIC(int32_t, IDX_NOTFOUND, 305419896)

extern Expression* isExpression(RootObject* o);

extern Dsymbol* isDsymbol(RootObject* o);

extern Type* isType(RootObject* o);

extern Tuple* isTuple(RootObject* o);

extern Parameter* isParameter(RootObject* o);

extern TemplateParameter* isTemplateParameter(RootObject* o);

extern bool isError(const RootObject* const o);

class Tuple : public RootObject
{
public:
    Array<RootObject*> objects;
    DYNCAST dyncast() const;
    const char* toChars() const;
    ~Tuple();
};

class TemplateDeclaration : public ScopeDsymbol
{
public:
    Array<TemplateParameter*>* parameters;
    Array<TemplateParameter*>* origParameters;
    Expression* constraint;
    void* instances;
    TemplateDeclaration* overnext;
    TemplateDeclaration* overroot;
    FuncDeclaration* funcroot;
    Dsymbol* onemember;
    bool literal;
    bool ismixin;
    bool isstatic;
    bool isTrivialAliasSeq;
    bool isTrivialAlias;
    bool deprecated_;
    Prot protection;
    int32_t inuse;
    TemplatePrevious* previous;
    Expression* lastConstraint;
    Array<Expression*> lastConstraintNegs;
    Array<RootObject*>* lastConstraintTiargs;
    Dsymbol* syntaxCopy(Dsymbol* _param_0);
    bool overloadInsert(Dsymbol* s);
    bool hasStaticCtorOrDtor();
    const char* kind() const;
    const char* toChars() const;
    const char* toCharsNoConstraints() const;
    const char* toCharsMaybeConstraints(bool includeConstraints) const;
    Prot prot();
    const char* getConstraintEvalError(const char*& tip);
    void formatParamsWithTiargs(Array<RootObject*>& tiargs, OutBuffer& buf);
    Scope* scopeForTemplateParameters(TemplateInstance* ti, Scope* sc);
    MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration* td2, Array<Expression*>* fargs);
    RootObject* declareParameter(Scope* sc, TemplateParameter* tp, RootObject* o);
    TemplateDeclaration* isTemplateDeclaration();
    TemplateTupleParameter* isVariadic();
    bool isDeprecated() const;
    bool isOverloadable() const;
    void accept(Visitor* v);
    ~TemplateDeclaration();
};

class TypeDeduced : public Type
{
public:
    Type* tded;
    Array<Expression*> argexps;
    Array<Type*> tparams;
    void update(Expression* e, Type* tparam);
    void update(Type* tt, Expression* e, Type* tparam);
    MATCH matchAll(Type* tt);
    ~TypeDeduced();
};

class TemplateParameter : public ASTNode
{
public:
    Loc loc;
    Identifier* ident;
    bool dependent;
    virtual TemplateTypeParameter* isTemplateTypeParameter();
    virtual TemplateValueParameter* isTemplateValueParameter();
    virtual TemplateAliasParameter* isTemplateAliasParameter();
    virtual TemplateThisParameter* isTemplateThisParameter();
    virtual TemplateTupleParameter* isTemplateTupleParameter();
    virtual TemplateParameter* syntaxCopy() = 0;
    virtual bool declareParameter(Scope* sc) = 0;
    virtual void print(RootObject* oarg, RootObject* oded) = 0;
    virtual RootObject* specialization() = 0;
    virtual RootObject* defaultArg(Loc instLoc, Scope* sc) = 0;
    virtual bool hasDefaultArg() = 0;
    const char* toChars() const;
    DYNCAST dyncast() const;
    virtual RootObject* dummyArg() = 0;
    void accept(Visitor* v);
};

class TemplateTypeParameter : public TemplateParameter
{
public:
    Type* specType;
    Type* defaultType;
    TemplateTypeParameter* isTemplateTypeParameter();
    TemplateParameter* syntaxCopy();
    bool declareParameter(Scope* sc);
    void print(RootObject* oarg, RootObject* oded);
    RootObject* specialization();
    RootObject* defaultArg(Loc instLoc, Scope* sc);
    bool hasDefaultArg();
    RootObject* dummyArg();
    void accept(Visitor* v);
};

class TemplateThisParameter : public TemplateTypeParameter
{
public:
    TemplateThisParameter* isTemplateThisParameter();
    TemplateParameter* syntaxCopy();
    void accept(Visitor* v);
};

class TemplateValueParameter : public TemplateParameter
{
public:
    Type* valType;
    Expression* specValue;
    Expression* defaultValue;
    TemplateValueParameter* isTemplateValueParameter();
    TemplateParameter* syntaxCopy();
    bool declareParameter(Scope* sc);
    void print(RootObject* oarg, RootObject* oded);
    RootObject* specialization();
    RootObject* defaultArg(Loc instLoc, Scope* sc);
    bool hasDefaultArg();
    RootObject* dummyArg();
    void accept(Visitor* v);
};

class TemplateAliasParameter : public TemplateParameter
{
public:
    Type* specType;
    RootObject* specAlias;
    RootObject* defaultAlias;
    TemplateAliasParameter* isTemplateAliasParameter();
    TemplateParameter* syntaxCopy();
    bool declareParameter(Scope* sc);
    void print(RootObject* oarg, RootObject* oded);
    RootObject* specialization();
    RootObject* defaultArg(Loc instLoc, Scope* sc);
    bool hasDefaultArg();
    RootObject* dummyArg();
    void accept(Visitor* v);
};

class TemplateTupleParameter : public TemplateParameter
{
public:
    TemplateTupleParameter* isTemplateTupleParameter();
    TemplateParameter* syntaxCopy();
    bool declareParameter(Scope* sc);
    void print(RootObject* oarg, RootObject* oded);
    RootObject* specialization();
    RootObject* defaultArg(Loc instLoc, Scope* sc);
    bool hasDefaultArg();
    RootObject* dummyArg();
    void accept(Visitor* v);
};

class TemplateInstance : public ScopeDsymbol
{
public:
    Identifier* name;
    Array<RootObject*>* tiargs;
    Array<RootObject*> tdtypes;
    Array<Module*> importedModules;
    Dsymbol* tempdecl;
    Dsymbol* enclosing;
    Dsymbol* aliasdecl;
    TemplateInstance* inst;
    ScopeDsymbol* argsym;
    size_t hash;
    Array<Expression*>* fargs;
    Array<TemplateInstance*>* deferred;
    Module* memberOf;
    TemplateInstance* tinst;
    TemplateInstance* tnext;
    Module* minst;
    uint16_t _nest;
    uint8_t inuse;
    BEGIN_ENUM_NUMERIC(uint32_t, Flag, FLAG, flag)
        ENUM_KEY_NUMERIC(uint32_t, semantictiargsdone, 32768u, Flag, FLAG, flag, F)
        ENUM_KEY_NUMERIC(uint32_t, havetempdecl, 16384u, Flag, FLAG, flag, F)
        ENUM_KEY_NUMERIC(uint32_t, gagged, 8192u, Flag, FLAG, flag, F)
        ENUM_KEY_NUMERIC(uint32_t, available, 8191u, Flag, FLAG, flag, F)
    END_ENUM_NUMERIC(uint32_t, Flag, FLAG, flag)

    Dsymbol* syntaxCopy(Dsymbol* s);
    Dsymbol* toAlias();
    const char* kind() const;
    bool oneMember(Dsymbol** ps, Identifier* ident);
    const char* toChars() const;
    const char* toPrettyCharsHelper();
    void printInstantiationTrace();
    Identifier* getIdent();
    bool equalsx(TemplateInstance* ti);
    size_t toHash();
    bool isDiscardable();
    bool needsCodegen();
    TemplateInstance* isTemplateInstance();
    void accept(Visitor* v);
    ~TemplateInstance();
};

class TemplateMixin : public TemplateInstance
{
public:
    TypeQualified* tqual;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    bool oneMember(Dsymbol** ps, Identifier* ident);
    bool hasPointers();
    void setFieldOffset(AggregateDeclaration* ad, uint32_t* poffset, bool isunion);
    const char* toChars() const;
    TemplateMixin* isTemplateMixin();
    void accept(Visitor* v);
    ~TemplateMixin();
};

ENUM_CONSTANT_NUMERIC(bool, isBuildingCompiler, false)

extern void genCppHdrFiles(Array<Module*>& ms);

class ToCppBuffer : public Visitor
{
public:
    BEGIN_ENUM(EnumKind, ENUMKIND, enumkind)
        ENUM_KEY(int32_t, Int, 0, EnumKind, ENUMKIND, enumkind, EK)
        ENUM_KEY(int32_t, Numeric, 1, EnumKind, ENUMKIND, enumkind, EK)
        ENUM_KEY(int32_t, String, 2, EnumKind, ENUMKIND, enumkind, EK)
        ENUM_KEY(int32_t, Enum, 3, EnumKind, ENUMKIND, enumkind, EK)
        ENUM_KEY(int32_t, Other, 4, EnumKind, ENUMKIND, enumkind, EK)
    END_ENUM(EnumKind, ENUMKIND, enumkind)

    typedef ASTCodegen AST;
    void* visited;
    void* forwarded;
    OutBuffer* fwdbuf;
    OutBuffer* checkbuf;
    OutBuffer* donebuf;
    OutBuffer* buf;
    AggregateDeclaration* adparent;
    ClassDeclaration* cdparent;
    TemplateDeclaration* tdparent;
    Identifier* ident;
    LINK linkage;
    bool forwardedAA;
    Type** origType;
    bool hasReal;
    bool hasDefaultEnum;
    bool hasNumericEnum;
    bool hasTypedEnum;
    bool hasAnonEnum;
    bool hasAnonNumericEnum;
    bool hasNumericConstant;
    bool hasTypedConstant;
    bool printIgnored;
    ToCppBuffer(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf);
    EnumKind getEnumKind(Type* type);
    void writeEnumTypeName(Type* type);
    void writeDeclEnd();
    void visit(Dsymbol* s);
    void visit(Import* i);
    void visit(AttribDeclaration* pd);
    void visit(LinkDeclaration* ld);
    void visit(CPPMangleDeclaration* md);
    void visit(Module* m);
    void visit(FuncDeclaration* fd);
    void visit(UnitTestDeclaration* utd);
    void visit(VarDeclaration* vd);
    void visit(TypeInfoDeclaration* tid);
    void visit(AliasDeclaration* ad);
    void visit(Nspace* ns);
    void visit(CPPNamespaceDeclaration* ns);
    void handleNspace(Identifier* name, Array<Dsymbol*>* members);
    void visit(AnonDeclaration* ad);
    bool memberField(VarDeclaration* vd);
    void visit(StructDeclaration* sd);
    void pushAlignToBuffer(uint32_t alignment);
    void popAlignToBuffer(uint32_t alignment);
    void includeSymbol(Dsymbol* ds);
    void visit(ClassDeclaration* cd);
    void visit(EnumDeclaration* ed);
    void visit(EnumMember* em);
    void typeToBuffer(Type* t, Identifier* ident);
    void visit(Type* t);
    void visit(TypeIdentifier* t);
    void visit(TypeBasic* t);
    void visit(TypePointer* t);
    void visit(TypeSArray* t);
    void visit(TypeAArray* t);
    void visit(TypeFunction* tf);
    void enumToBuffer(EnumDeclaration* ed);
    void visit(TypeEnum* t);
    void visit(TypeStruct* t);
    void visit(TypeDArray* t);
    void visitTi(TemplateInstance* ti);
    void visit(TemplateDeclaration* td);
    void visit(TypeClass* t);
    void funcToBuffer(TypeFunction* tf, FuncDeclaration* fd);
    void visit(Parameter* p);
    void visit(Expression* e);
    void visit(NullExp* e);
    void visit(ArrayLiteralExp* e);
    void visit(StringExp* e);
    void visit(RealExp* e);
    void visit(IntegerExp* e);
    void visitInteger(dinteger_t v, Type* t);
    void visit(StructLiteralExp* sle);
};

class DebugSymbol : public Dsymbol
{
public:
    uint32_t level;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* toChars() const;
    void addMember(Scope* sc, ScopeDsymbol* sds);
    const char* kind() const;
    DebugSymbol* isDebugSymbol();
    void accept(Visitor* v);
};

class VersionSymbol : public Dsymbol
{
public:
    uint32_t level;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* toChars() const;
    void addMember(Scope* sc, ScopeDsymbol* sds);
    const char* kind() const;
    VersionSymbol* isVersionSymbol();
    void accept(Visitor* v);
};

ENUM_CONSTANT_NUMERIC(bool, LOGSEMANTIC, false)

extern void expandTuples(Array<Expression*>* exps);

struct UnionExp
{
    Expression* exp();
    Expression* copy();
    #pragma pack(push, 8)
    union __AnonStruct__u
    {
        char exp[40LLU];
        char integerexp[48LLU];
        char errorexp[40LLU];
        char realexp[64LLU];
        char complexexp[80LLU];
        char symoffexp[72LLU];
        char stringexp[60LLU];
        char arrayliteralexp[57LLU];
        char assocarrayliteralexp[57LLU];
        char structliteralexp[95LLU];
        char nullexp[40LLU];
        char dotvarexp[65LLU];
        char addrexp[56LLU];
        char indexexp[82LLU];
        char sliceexp[83LLU];
        char vectorexp[69LLU];
        __AnonStruct__u()
        {
        }
    };
    #pragma pack(pop)

    // Ignoring var u alignment 8
    __AnonStruct__u u;
    UnionExp()
    {
    }
};

BEGIN_ENUM_NUMERIC(uint8_t, OwnedBy, OWNEDBY, ownedby)
    ENUM_KEY_NUMERIC(uint8_t, code, 0u, OwnedBy, OWNEDBY, ownedby, OB)
    ENUM_KEY_NUMERIC(uint8_t, ctfe, 1u, OwnedBy, OWNEDBY, ownedby, OB)
    ENUM_KEY_NUMERIC(uint8_t, cache, 2u, OwnedBy, OWNEDBY, ownedby, OB)
END_ENUM_NUMERIC(uint8_t, OwnedBy, OWNEDBY, ownedby)

ENUM_CONSTANT_NUMERIC(int32_t, WANTvalue, 0)

ENUM_CONSTANT_NUMERIC(int32_t, WANTexpand, 1)

class IntegerExp : public Expression
{
public:
    dinteger_t value;
    static IntegerExp* create(Loc loc, dinteger_t value, Type* type);
    static void emplace(UnionExp* pue, Loc loc, dinteger_t value, Type* type);
    bool equals(const RootObject* const o) const;
    dinteger_t toInteger();
    _d_real toReal();
    _d_real toImaginary();
    complex_t toComplex();
    bool isBool(bool result);
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
    dinteger_t getInteger();
    void setInteger(dinteger_t value);
    Expression* syntaxCopy();
    static IntegerExp* createBool(bool b);
};

class ErrorExp : public Expression
{
public:
    static ErrorExp* get();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
    static ErrorExp* errorexp;
};

class VoidInitExp : public Expression
{
public:
    VarDeclaration* var;
    const char* toChars() const;
    void accept(Visitor* v);
};

class RealExp : public Expression
{
public:
    _d_real value;
    static RealExp* create(Loc loc, _d_real value, Type* type);
    static void emplace(UnionExp* pue, Loc loc, _d_real value, Type* type);
    bool equals(const RootObject* const o) const;
    dinteger_t toInteger();
    uinteger_t toUInteger();
    _d_real toReal();
    _d_real toImaginary();
    complex_t toComplex();
    bool isBool(bool result);
    void accept(Visitor* v);
};

class ComplexExp : public Expression
{
public:
    complex_t value;
    static ComplexExp* create(Loc loc, complex_t value, Type* type);
    static void emplace(UnionExp* pue, Loc loc, complex_t value, Type* type);
    bool equals(const RootObject* const o) const;
    dinteger_t toInteger();
    uinteger_t toUInteger();
    _d_real toReal();
    _d_real toImaginary();
    complex_t toComplex();
    bool isBool(bool result);
    void accept(Visitor* v);
};

class IdentifierExp : public Expression
{
public:
    Identifier* ident;
    static IdentifierExp* create(Loc loc, Identifier* ident);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class DollarExp : public IdentifierExp
{
public:
    void accept(Visitor* v);
};

class DsymbolExp : public Expression
{
public:
    Dsymbol* s;
    bool hasOverloads;
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class ThisExp : public Expression
{
public:
    VarDeclaration* var;
    ThisExp(const Loc& loc, const TOK tok);
    Expression* syntaxCopy();
    bool isBool(bool result);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class SuperExp : public ThisExp
{
public:
    void accept(Visitor* v);
};

class NullExp : public Expression
{
public:
    bool equals(const RootObject* const o) const;
    bool isBool(bool result);
    StringExp* toStringExp();
    void accept(Visitor* v);
};

class StringExp : public Expression
{
public:
    union
    {
        char* string;
        char16_t* wstring;
        char32_t* dstring;
    };
    size_t len;
    uint8_t sz;
    uint8_t committed;
    ENUM_CONSTANT_NUMERIC(char, NoPostfix, 0u)

    char postfix;
    OwnedBy ownedByCtfe;
    static StringExp* create(Loc loc, char* s);
    static StringExp* create(Loc loc, void* string, size_t len);
    static void emplace(UnionExp* pue, Loc loc, char* s);
    bool equals(const RootObject* const o) const;
    size_t numberOfCodeUnits(int32_t tynto = 0) const;
    void writeTo(void* dest, bool zero, int32_t tyto = 0) const;
    char32_t getCodeUnit(size_t i) const;
    void setCodeUnit(size_t i, char32_t c);
    StringExp* toStringExp();
    StringExp* toUTF8(Scope* sc);
    int32_t compare(const StringExp* const se2) const;
    bool isBool(bool result);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    uint32_t charAt(uinteger_t i) const;
    void accept(Visitor* v);
};

class TupleExp : public Expression
{
public:
    Expression* e0;
    Array<Expression*>* exps;
    static TupleExp* create(Loc loc, Array<Expression*>* exps);
    TupleExp* toTupleExp();
    Expression* syntaxCopy();
    bool equals(const RootObject* const o) const;
    void accept(Visitor* v);
};

class ArrayLiteralExp : public Expression
{
public:
    Expression* basis;
    Array<Expression*>* elements;
    OwnedBy ownedByCtfe;
    static ArrayLiteralExp* create(Loc loc, Array<Expression*>* elements);
    static void emplace(UnionExp* pue, Loc loc, Array<Expression*>* elements);
    Expression* syntaxCopy();
    bool equals(const RootObject* const o) const;
    Expression* getElement(size_t i);
    Expression* opIndex(size_t i);
    bool isBool(bool result);
    StringExp* toStringExp();
    void accept(Visitor* v);
};

class AssocArrayLiteralExp : public Expression
{
public:
    Array<Expression*>* keys;
    Array<Expression*>* values;
    OwnedBy ownedByCtfe;
    bool equals(const RootObject* const o) const;
    Expression* syntaxCopy();
    bool isBool(bool result);
    void accept(Visitor* v);
};

ENUM_CONSTANT_NUMERIC(int32_t, stageScrub, 1)

ENUM_CONSTANT_NUMERIC(int32_t, stageSearchPointers, 2)

ENUM_CONSTANT_NUMERIC(int32_t, stageOptimize, 4)

ENUM_CONSTANT_NUMERIC(int32_t, stageApply, 8)

ENUM_CONSTANT_NUMERIC(int32_t, stageInlineScan, 16)

ENUM_CONSTANT_NUMERIC(int32_t, stageToCBuffer, 32)

class StructLiteralExp : public Expression
{
public:
    StructDeclaration* sd;
    Array<Expression*>* elements;
    Type* stype;
    Symbol* sym;
    StructLiteralExp* origin;
    StructLiteralExp* inlinecopy;
    int32_t stageflags;
    bool useStaticInit;
    bool isOriginal;
    OwnedBy ownedByCtfe;
    static StructLiteralExp* create(Loc loc, StructDeclaration* sd, void* elements, Type* stype);
    bool equals(const RootObject* const o) const;
    Expression* syntaxCopy();
    Expression* getField(Type* type, uint32_t offset);
    int32_t getFieldIndex(Type* type, uint32_t offset);
    Expression* addDtorHook(Scope* sc);
    void accept(Visitor* v);
};

class TypeExp : public Expression
{
public:
    Expression* syntaxCopy();
    bool checkType();
    bool checkValue();
    void accept(Visitor* v);
};

class ScopeExp : public Expression
{
public:
    ScopeDsymbol* sds;
    Expression* syntaxCopy();
    bool checkType();
    bool checkValue();
    void accept(Visitor* v);
};

class TemplateExp : public Expression
{
public:
    TemplateDeclaration* td;
    FuncDeclaration* fd;
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    bool checkType();
    bool checkValue();
    void accept(Visitor* v);
};

class NewExp : public Expression
{
public:
    Expression* thisexp;
    Array<Expression*>* newargs;
    Type* newtype;
    Array<Expression*>* arguments;
    Expression* argprefix;
    CtorDeclaration* member;
    NewDeclaration* allocator;
    bool onstack;
    bool thrownew;
    static NewExp* create(Loc loc, Expression* thisexp, Array<Expression*>* newargs, Type* newtype, Array<Expression*>* arguments);
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class NewAnonClassExp : public Expression
{
public:
    Expression* thisexp;
    Array<Expression*>* newargs;
    ClassDeclaration* cd;
    Array<Expression*>* arguments;
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class SymbolExp : public Expression
{
public:
    Declaration* var;
    Dsymbol* originalScope;
    bool hasOverloads;
    void accept(Visitor* v);
};

class SymOffExp : public SymbolExp
{
public:
    dinteger_t offset;
    bool isBool(bool result);
    void accept(Visitor* v);
};

class VarExp : public SymbolExp
{
public:
    bool delegateWasExtracted;
    static VarExp* create(Loc loc, Declaration* var, bool hasOverloads = true);
    bool equals(const RootObject* const o) const;
    Modifiable checkModifiable(Scope* sc, int32_t flag);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
    Expression* syntaxCopy();
};

class OverExp : public Expression
{
public:
    OverloadSet* vars;
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class FuncExp : public Expression
{
public:
    FuncLiteralDeclaration* fd;
    TemplateDeclaration* td;
    TOK tok;
    bool equals(const RootObject* const o) const;
    Expression* syntaxCopy();
    const char* toChars() const;
    bool checkType();
    bool checkValue();
    void accept(Visitor* v);
};

class DeclarationExp : public Expression
{
public:
    Dsymbol* declaration;
    Expression* syntaxCopy();
    bool hasCode();
    void accept(Visitor* v);
};

class TypeidExp : public Expression
{
public:
    RootObject* obj;
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class TraitsExp : public Expression
{
public:
    Identifier* ident;
    Array<RootObject*>* args;
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class HaltExp : public Expression
{
public:
    void accept(Visitor* v);
};

class IsExp : public Expression
{
public:
    Type* targ;
    Identifier* id;
    Type* tspec;
    Array<TemplateParameter*>* parameters;
    TOK tok;
    TOK tok2;
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class UnaExp : public Expression
{
public:
    Expression* e1;
    Type* att1;
    Expression* syntaxCopy();
    Expression* incompatibleTypes();
    void setNoderefOperand();
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

typedef UnionExp(*fp_t)(Loc& loc, Type , Expression , Expression );

typedef bool(*fp2_t)(Loc& loc, TOK , Expression , Expression );

class BinExp : public Expression
{
public:
    Expression* e1;
    Expression* e2;
    Type* att1;
    Type* att2;
    Expression* syntaxCopy();
    Expression* incompatibleTypes();
    void setNoderefOperands();
    Expression* reorderSettingAAElem(Scope* sc);
    void accept(Visitor* v);
};

class BinAssignExp : public BinExp
{
public:
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* ex);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class CompileExp : public Expression
{
public:
    Array<Expression*>* exps;
    Expression* syntaxCopy();
    bool equals(const RootObject* const o) const;
    void accept(Visitor* v);
};

class ImportExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

class AssertExp : public UnaExp
{
public:
    Expression* msg;
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class DotIdExp : public UnaExp
{
public:
    Identifier* ident;
    bool noderef;
    bool wantsym;
    static DotIdExp* create(Loc loc, Expression* e, Identifier* ident);
    void accept(Visitor* v);
};

class DotTemplateExp : public UnaExp
{
public:
    TemplateDeclaration* td;
    void accept(Visitor* v);
};

class DotVarExp : public UnaExp
{
public:
    Declaration* var;
    bool hasOverloads;
    Modifiable checkModifiable(Scope* sc, int32_t flag);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class DotTemplateInstanceExp : public UnaExp
{
public:
    TemplateInstance* ti;
    Expression* syntaxCopy();
    bool findTempDecl(Scope* sc);
    void accept(Visitor* v);
};

class DelegateExp : public UnaExp
{
public:
    FuncDeclaration* func;
    bool hasOverloads;
    VarDeclaration* vthis2;
    void accept(Visitor* v);
};

class DotTypeExp : public UnaExp
{
public:
    Dsymbol* sym;
    void accept(Visitor* v);
};

class CallExp : public UnaExp
{
public:
    Array<Expression*>* arguments;
    FuncDeclaration* f;
    bool directcall;
    bool inDebugStatement;
    VarDeclaration* vthis2;
    static CallExp* create(Loc loc, Expression* e, Array<Expression*>* exps);
    static CallExp* create(Loc loc, Expression* e);
    static CallExp* create(Loc loc, Expression* e, Expression* earg1);
    static CallExp* create(Loc loc, FuncDeclaration* fd, Expression* earg1);
    Expression* syntaxCopy();
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* addDtorHook(Scope* sc);
    void accept(Visitor* v);
};

class AddrExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

class PtrExp : public UnaExp
{
public:
    Modifiable checkModifiable(Scope* sc, int32_t flag);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class NegExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

class UAddExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

class ComExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

class NotExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

class DeleteExp : public UnaExp
{
public:
    bool isRAII;
    Expression* toBoolean(Scope* sc);
    void accept(Visitor* v);
};

class CastExp : public UnaExp
{
public:
    Type* to;
    uint8_t mod;
    Expression* syntaxCopy();
    Expression* addDtorHook(Scope* sc);
    void accept(Visitor* v);
};

class VectorExp : public UnaExp
{
public:
    TypeVector* to;
    uint32_t dim;
    OwnedBy ownedByCtfe;
    static VectorExp* create(Loc loc, Expression* e, Type* t);
    static void emplace(UnionExp* pue, Loc loc, Expression* e, Type* type);
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class VectorArrayExp : public UnaExp
{
public:
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class SliceExp : public UnaExp
{
public:
    Expression* upr;
    Expression* lwr;
    VarDeclaration* lengthVar;
    bool upperIsInBounds;
    bool lowerIsLessThanUpper;
    bool arrayop;
    Expression* syntaxCopy();
    Modifiable checkModifiable(Scope* sc, int32_t flag);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    bool isBool(bool result);
    void accept(Visitor* v);
};

class ArrayLengthExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

class ArrayExp : public UnaExp
{
public:
    Array<Expression*>* arguments;
    size_t currentDimension;
    VarDeclaration* lengthVar;
    Expression* syntaxCopy();
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class DotExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class CommaExp : public BinExp
{
public:
    bool isGenerated;
    bool allowCommaExp;
    Modifiable checkModifiable(Scope* sc, int32_t flag);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    bool isBool(bool result);
    Expression* toBoolean(Scope* sc);
    Expression* addDtorHook(Scope* sc);
    void accept(Visitor* v);
    static void allow(Expression* exp);
};

class IntervalExp : public Expression
{
public:
    Expression* lwr;
    Expression* upr;
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

class DelegatePtrExp : public UnaExp
{
public:
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class DelegateFuncptrExp : public UnaExp
{
public:
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class IndexExp : public BinExp
{
public:
    VarDeclaration* lengthVar;
    bool modifiable;
    bool indexIsInBounds;
    Expression* syntaxCopy();
    Modifiable checkModifiable(Scope* sc, int32_t flag);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class PostExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class PreExp : public UnaExp
{
public:
    void accept(Visitor* v);
};

BEGIN_ENUM(MemorySet, MEMORYSET, memoryset)
    ENUM_KEY(int32_t, none, 0, MemorySet, MEMORYSET, memoryset, MS)
    ENUM_KEY(int32_t, blockAssign, 1, MemorySet, MEMORYSET, memoryset, MS)
    ENUM_KEY(int32_t, referenceInit, 2, MemorySet, MEMORYSET, memoryset, MS)
END_ENUM(MemorySet, MEMORYSET, memoryset)

class AssignExp : public BinExp
{
public:
    MemorySet memset;
    AssignExp(const Loc& loc, TOK tok, Expression* e1, Expression* e2);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* ex);
    Expression* toBoolean(Scope* sc);
    void accept(Visitor* v);
};

class ConstructExp : public AssignExp
{
public:
    void accept(Visitor* v);
};

class BlitExp : public AssignExp
{
public:
    void accept(Visitor* v);
};

class AddAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class MinAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class MulAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class DivAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class ModAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class AndAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class OrAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class XorAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class PowAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class ShlAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class ShrAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class UshrAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class CatAssignExp : public BinAssignExp
{
public:
    void accept(Visitor* v);
};

class CatElemAssignExp : public CatAssignExp
{
public:
    void accept(Visitor* v);
};

class CatDcharAssignExp : public CatAssignExp
{
public:
    void accept(Visitor* v);
};

class AddExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class MinExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class CatExp : public BinExp
{
public:
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

class MulExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class DivExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class ModExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class PowExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class ShlExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class ShrExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class UshrExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class AndExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class OrExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class XorExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class LogicalExp : public BinExp
{
public:
    Expression* toBoolean(Scope* sc);
    void accept(Visitor* v);
};

class CmpExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class InExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class RemoveExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class EqualExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class IdentityExp : public BinExp
{
public:
    void accept(Visitor* v);
};

class CondExp : public BinExp
{
public:
    Expression* econd;
    Expression* syntaxCopy();
    Modifiable checkModifiable(Scope* sc, int32_t flag);
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* ex);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    Expression* toBoolean(Scope* sc);
    void hookDtors(Scope* sc);
    void accept(Visitor* v);
};

class DefaultInitExp : public Expression
{
public:
    void accept(Visitor* v);
};

class FileInitExp : public DefaultInitExp
{
public:
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

class LineInitExp : public DefaultInitExp
{
public:
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

class ModuleInitExp : public DefaultInitExp
{
public:
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

class FuncInitExp : public DefaultInitExp
{
public:
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

class PrettyFuncInitExp : public DefaultInitExp
{
public:
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

class ObjcClassReferenceExp : public Expression
{
public:
    ClassDeclaration* classDeclaration;
    void accept(Visitor* v);
};

ENUM_CONSTANT_NUMERIC(bool, LOGSEMANTIC, false)

extern Expression* resolveProperties(Scope* sc, Expression* e);

extern Expression* expressionSemantic(Expression* e, Scope* sc);

BEGIN_ENUM(ILS, ILS, ils)
    ENUM_KEY(int32_t, uninitialized, 0, ILS, ILS, ils, ILS)
    ENUM_KEY(int32_t, no, 1, ILS, ILS, ils, ILS)
    ENUM_KEY(int32_t, yes, 2, ILS, ILS, ils, ILS)
END_ENUM(ILS, ILS, ils)

class NrvoWalker : public StatementRewriteWalker
{
public:
    FuncDeclaration* fd;
    Scope* sc;
    void visit(ReturnStatement* s);
    void visit(TryFinallyStatement* s);
};

BEGIN_ENUM_NUMERIC(uint32_t, FUNCFLAG, FUNCFLAG, funcflag)
    ENUM_KEY_NUMERIC(uint32_t, purityInprocess, 1u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, safetyInprocess, 2u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, nothrowInprocess, 4u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, nogcInprocess, 8u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, returnInprocess, 16u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, inlineScanned, 32u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, inferScope, 64u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, hasCatches, 128u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, compileTimeOnly, 256u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, printf, 512u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
    ENUM_KEY_NUMERIC(uint32_t, scanf, 1024u, FUNCFLAG, FUNCFLAG, funcflag, FUNCFLAG)
END_ENUM_NUMERIC(uint32_t, FUNCFLAG, FUNCFLAG, funcflag)

struct Ensure
{
    Identifier* id;
    Statement* ensure;
    Ensure syntaxCopy();
    static Array<Ensure>* arraySyntaxCopy(Array<Ensure>* a);
    Ensure() :
        id(),
        ensure()
    {
    }
};

class FuncDeclaration : public Declaration
{
public:
    Array<Statement*>* frequires;
    Array<Ensure>* fensures;
    Statement* frequire;
    Statement* fensure;
    Statement* fbody;
    Array<FuncDeclaration*> foverrides;
    FuncDeclaration* fdrequire;
    FuncDeclaration* fdensure;
    Array<Expression*>* fdrequireParams;
    Array<Expression*>* fdensureParams;
    char* mangleString;
    VarDeclaration* vresult;
    LabelDsymbol* returnLabel;
    DsymbolTable* localsymtab;
    VarDeclaration* vthis;
    bool isThis2;
    VarDeclaration* v_arguments;
    VarDeclaration* v_argptr;
    Array<VarDeclaration*>* parameters;
    DsymbolTable* labtab;
    Dsymbol* overnext;
    FuncDeclaration* overnext0;
    Loc endloc;
    int32_t vtblIndex;
    bool naked;
    bool generated;
    bool hasAlwaysInlines;
    uint8_t isCrtCtorDtor;
    ILS inlineStatusStmt;
    ILS inlineStatusExp;
    PINLINE inlining;
    int32_t inlineNest;
    bool eh_none;
    bool semantic3Errors;
    ForeachStatement* fes;
    BaseClass* interfaceVirtual;
    bool introducing;
    Type* tintro;
    bool inferRetType;
    StorageClass storage_class2;
    int32_t hasReturnExp;
    bool nrvo_can;
    VarDeclaration* nrvo_var;
    Symbol* shidden;
    Array<ReturnStatement*>* returns;
    Array<GotoStatement*>* gotos;
    BUILTIN builtin;
    int32_t tookAddressOf;
    bool requiresClosure;
    Array<VarDeclaration*> closureVars;
    Array<VarDeclaration*> outerVars;
    Array<FuncDeclaration*> siblingCallers;
    Array<FuncDeclaration*>* inlinedNestedCallees;
    uint32_t flags;
    ObjcFuncDeclaration objc;
    static FuncDeclaration* create(const Loc& loc, const Loc& endloc, Identifier* id, StorageClass storage_class, Type* type);
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool functionSemantic();
    bool functionSemantic3();
    bool equals(const RootObject* const o) const;
    int32_t overrides(FuncDeclaration* fd);
    int32_t findVtblIndex(Array<Dsymbol*>* vtbl, int32_t dim);
    BaseClass* overrideInterface();
    bool overloadInsert(Dsymbol* s);
    bool inUnittest();
    MATCH leastAsSpecialized(FuncDeclaration* g);
    LabelDsymbol* searchLabel(Identifier* ident);
    int32_t getLevel(FuncDeclaration* fd, int32_t intypeof);
    int32_t getLevelAndCheck(const Loc& loc, Scope* sc, FuncDeclaration* fd, Declaration* decl);
    ENUM_CONSTANT_NUMERIC(int32_t, LevelError, -2)

    const char* toPrettyChars(bool QualifyTypes = false);
    const char* toFullSignature();
    bool isMain() const;
    bool isCMain() const;
    bool isWinMain() const;
    bool isDllMain() const;
    bool isRtInit() const;
    bool isExport() const;
    bool isImportedSymbol() const;
    bool isCodeseg() const;
    bool isOverloadable() const;
    bool isAbstract();
    bool canInferAttributes(Scope* sc);
    void initInferAttributes();
    PURE isPure();
    PURE isPureBypassingInference();
    bool isSafe();
    bool isSafeBypassingInference();
    bool isTrusted();
    bool isNogc();
    bool isNogcBypassingInference();
    bool isTypeIsolatedIndirect(Type* t);
    virtual bool isNested() const;
    AggregateDeclaration* isThis();
    bool needThis();
    bool isVirtualMethod();
    virtual bool isVirtual() const;
    bool isFinalFunc() const;
    virtual bool addPreInvariant();
    virtual bool addPostInvariant();
    const char* kind() const;
    bool isUnique() const;
    bool needsClosure();
    bool hasNestedFrameRefs();
    static bool needsFensure(FuncDeclaration* fd);
    void buildEnsureRequire();
    ParameterList getParameterList();
    static FuncDeclaration* genCfunc(Array<Parameter*>* fparams, Type* treturn, const char* name, StorageClass stc = 0);
    static FuncDeclaration* genCfunc(Array<Parameter*>* fparams, Type* treturn, Identifier* id, StorageClass stc = 0);
    bool checkNrvo();
    FuncDeclaration* isFuncDeclaration();
    virtual FuncDeclaration* toAliasFunc();
    void accept(Visitor* v);
    ~FuncDeclaration();
};

BEGIN_ENUM_NUMERIC(uint8_t, FuncResolveFlag, FUNCRESOLVEFLAG, funcresolveflag)
    ENUM_KEY_NUMERIC(uint8_t, standard, 0u, FuncResolveFlag, FUNCRESOLVEFLAG, funcresolveflag, FRF)
    ENUM_KEY_NUMERIC(uint8_t, quiet, 1u, FuncResolveFlag, FUNCRESOLVEFLAG, funcresolveflag, FRF)
    ENUM_KEY_NUMERIC(uint8_t, overloadOnly, 2u, FuncResolveFlag, FUNCRESOLVEFLAG, funcresolveflag, FRF)
END_ENUM_NUMERIC(uint8_t, FuncResolveFlag, FUNCRESOLVEFLAG, funcresolveflag)

class FuncAliasDeclaration : public FuncDeclaration
{
public:
    FuncDeclaration* funcalias;
    bool hasOverloads;
    FuncAliasDeclaration* isFuncAliasDeclaration();
    const char* kind() const;
    FuncDeclaration* toAliasFunc();
    void accept(Visitor* v);
    ~FuncAliasDeclaration();
};

class FuncLiteralDeclaration : public FuncDeclaration
{
public:
    TOK tok;
    Type* treq;
    bool deferToObj;
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool isNested() const;
    AggregateDeclaration* isThis();
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    void modifyReturns(Scope* sc, Type* tret);
    FuncLiteralDeclaration* isFuncLiteralDeclaration();
    const char* kind() const;
    const char* toPrettyChars(bool QualifyTypes = false);
    void accept(Visitor* v);
    ~FuncLiteralDeclaration();
};

class CtorDeclaration : public FuncDeclaration
{
public:
    bool isCpCtor;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    const char* toChars() const;
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    CtorDeclaration* isCtorDeclaration();
    void accept(Visitor* v);
    ~CtorDeclaration();
};

class PostBlitDeclaration : public FuncDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    bool overloadInsert(Dsymbol* s);
    PostBlitDeclaration* isPostBlitDeclaration();
    void accept(Visitor* v);
    ~PostBlitDeclaration();
};

class DtorDeclaration : public FuncDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    const char* toChars() const;
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    bool overloadInsert(Dsymbol* s);
    DtorDeclaration* isDtorDeclaration();
    void accept(Visitor* v);
    ~DtorDeclaration();
};

class StaticCtorDeclaration : public FuncDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    AggregateDeclaration* isThis();
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    bool hasStaticCtorOrDtor();
    StaticCtorDeclaration* isStaticCtorDeclaration();
    void accept(Visitor* v);
    ~StaticCtorDeclaration();
};

class SharedStaticCtorDeclaration : public StaticCtorDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    SharedStaticCtorDeclaration* isSharedStaticCtorDeclaration();
    void accept(Visitor* v);
    ~SharedStaticCtorDeclaration();
};

class StaticDtorDeclaration : public FuncDeclaration
{
public:
    VarDeclaration* vgate;
    Dsymbol* syntaxCopy(Dsymbol* s);
    AggregateDeclaration* isThis();
    bool isVirtual() const;
    bool hasStaticCtorOrDtor();
    bool addPreInvariant();
    bool addPostInvariant();
    StaticDtorDeclaration* isStaticDtorDeclaration();
    void accept(Visitor* v);
    ~StaticDtorDeclaration();
};

class SharedStaticDtorDeclaration : public StaticDtorDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    SharedStaticDtorDeclaration* isSharedStaticDtorDeclaration();
    void accept(Visitor* v);
    ~SharedStaticDtorDeclaration();
};

class InvariantDeclaration : public FuncDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    InvariantDeclaration* isInvariantDeclaration();
    void accept(Visitor* v);
    ~InvariantDeclaration();
};

class UnitTestDeclaration : public FuncDeclaration
{
public:
    char* codedoc;
    Array<FuncDeclaration*> deferredNested;
    Dsymbol* syntaxCopy(Dsymbol* s);
    AggregateDeclaration* isThis();
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    UnitTestDeclaration* isUnitTestDeclaration();
    void accept(Visitor* v);
    ~UnitTestDeclaration();
};

class NewDeclaration : public FuncDeclaration
{
public:
    ParameterList parameterList;
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    bool isVirtual() const;
    bool addPreInvariant();
    bool addPostInvariant();
    NewDeclaration* isNewDeclaration();
    void accept(Visitor* v);
    ~NewDeclaration();
};

class ObjcGlue
{
public:
    static void initialize();
};

ENUM_CONSTANT_NUMERIC(int32_t, TEST_EMIT_ALL, 0)

extern void genhdrfile(Module* m);

extern void moduleToBuffer(OutBuffer* buf, Module* m);

extern const char* parametersTypeToChars(ParameterList pl);

BEGIN_ENUM(NeedInterpret, NEEDINTERPRET, needinterpret)
    ENUM_KEY(int32_t, INITnointerpret, 0, NeedInterpret, NEEDINTERPRET, needinterpret, NI)
    ENUM_KEY(int32_t, INITinterpret, 1, NeedInterpret, NEEDINTERPRET, needinterpret, NI)
END_ENUM(NeedInterpret, NEEDINTERPRET, needinterpret)

BEGIN_ENUM_NUMERIC(uint8_t, InitKind, INITKIND, initkind)
    ENUM_KEY_NUMERIC(uint8_t, void_, 0u, InitKind, INITKIND, initkind, IK)
    ENUM_KEY_NUMERIC(uint8_t, error, 1u, InitKind, INITKIND, initkind, IK)
    ENUM_KEY_NUMERIC(uint8_t, struct_, 2u, InitKind, INITKIND, initkind, IK)
    ENUM_KEY_NUMERIC(uint8_t, array, 3u, InitKind, INITKIND, initkind, IK)
    ENUM_KEY_NUMERIC(uint8_t, exp, 4u, InitKind, INITKIND, initkind, IK)
END_ENUM_NUMERIC(uint8_t, InitKind, INITKIND, initkind)

class Initializer : public ASTNode
{
public:
    Loc loc;
    InitKind kind;
    const char* toChars() const;
    ErrorInitializer* isErrorInitializer();
    VoidInitializer* isVoidInitializer();
    StructInitializer* isStructInitializer();
    ArrayInitializer* isArrayInitializer();
    ExpInitializer* isExpInitializer();
    void accept(Visitor* v);
};

class VoidInitializer : public Initializer
{
public:
    Type* type;
    void accept(Visitor* v);
};

class ErrorInitializer : public Initializer
{
public:
    void accept(Visitor* v);
};

class StructInitializer : public Initializer
{
public:
    Array<Identifier*> field;
    Array<Initializer*> value;
    void accept(Visitor* v);
    ~StructInitializer();
};

class ArrayInitializer : public Initializer
{
public:
    Array<Expression*> index;
    Array<Initializer*> value;
    uint32_t dim;
    Type* type;
    bool sem;
    bool isAssociativeArray() const;
    void accept(Visitor* v);
    ~ArrayInitializer();
};

class ExpInitializer : public Initializer
{
public:
    bool expandTuples;
    Expression* exp;
    void accept(Visitor* v);
};

extern bool hasNonConstPointers(Expression* e);

extern Initializer* initializerSemantic(Initializer* init, Scope* sc, Type* t, NeedInterpret needInterpret);

extern Expression* initializerToExpression(Initializer* init, Type* itype);

ENUM_CONSTANT_NUMERIC(int32_t, COST_MAX, 250)

extern void json_generate(OutBuffer* buf, Array<Module*>* modules);

ENUM_CONSTANT(const char*, jsonFieldNames, "`compilerInfo`, `buildInfo`, `modules`, `semantics`")

extern JsonFieldFlags tryParseJsonField(const char* fieldName);

ENUM_CONSTANT_NUMERIC(bool, LOG, false)

extern Library* LibElf_factory();

extern "C" void printInternalFailure(_IO_FILE* stream);

extern void generateJson(Array<Module*>* modules);

typedef int32_t(*MainFunc)(DArray< DArray< char > > args);

extern "C" DArray< DArray< char > > rt_options;

extern "C" int32_t main(int32_t argc, char** argv);

extern "C" int32_t _Dmain(DArray< DArray< char > > _param_0);

extern "C" void printGlobalConfigs(_IO_FILE* stream);

extern "C" void flushMixins();

ENUM_CONSTANT_NUMERIC(int32_t, LOGDOTEXP, 0)

ENUM_CONSTANT_NUMERIC(int32_t, LOGDEFAULTINIT, 0)

ENUM_CONSTANT_NUMERIC(uint64_t, SIZE_INVALID, 18446744073709551615LLU)

BEGIN_ENUM(ENUMTY, ENUMTY, enumty)
    ENUM_KEY(int32_t, Tarray, 0, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tsarray, 1, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Taarray, 2, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tpointer, 3, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Treference, 4, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tfunction, 5, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tident, 6, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tclass, 7, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tstruct, 8, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tenum, 9, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tdelegate, 10, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tnone, 11, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tvoid, 12, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tint8, 13, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tuns8, 14, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tint16, 15, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tuns16, 16, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tint32, 17, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tuns32, 18, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tint64, 19, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tuns64, 20, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tfloat32, 21, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tfloat64, 22, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tfloat80, 23, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Timaginary32, 24, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Timaginary64, 25, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Timaginary80, 26, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tcomplex32, 27, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tcomplex64, 28, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tcomplex80, 29, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tbool, 30, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tchar, 31, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Twchar, 32, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tdchar, 33, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Terror, 34, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tinstance, 35, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Ttypeof, 36, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Ttuple, 37, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tslice, 38, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Treturn, 39, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tnull, 40, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tvector, 41, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tint128, 42, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tuns128, 43, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Ttraits, 44, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, Tmixin, 45, ENUMTY, ENUMTY, enumty, ENUMTY)
    ENUM_KEY(int32_t, TMAX, 46, ENUMTY, ENUMTY, enumty, ENUMTY)
END_ENUM(ENUMTY, ENUMTY, enumty)

typedef uint8_t TY;

BEGIN_ENUM(MODFlags, MODFLAGS, modflags)
    ENUM_KEY(int32_t, const_, 1, MODFlags, MODFLAGS, modflags, MODF)
    ENUM_KEY(int32_t, immutable_, 4, MODFlags, MODFLAGS, modflags, MODF)
    ENUM_KEY(int32_t, shared_, 2, MODFlags, MODFLAGS, modflags, MODF)
    ENUM_KEY(int32_t, wild, 8, MODFlags, MODFLAGS, modflags, MODF)
    ENUM_KEY(int32_t, wildconst, 9, MODFlags, MODFLAGS, modflags, MODF)
    ENUM_KEY(int32_t, mutable, 16, MODFlags, MODFLAGS, modflags, MODF)
END_ENUM(MODFlags, MODFLAGS, modflags)

typedef uint8_t MOD;

BEGIN_ENUM(DotExpFlag, DOTEXPFLAG, dotexpflag)
    ENUM_KEY(int32_t, gag, 1, DotExpFlag, DOTEXPFLAG, dotexpflag, DEF)
    ENUM_KEY(int32_t, noDeref, 2, DotExpFlag, DOTEXPFLAG, dotexpflag, DEF)
END_ENUM(DotExpFlag, DOTEXPFLAG, dotexpflag)

class TypeError : public Type
{
public:
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc);
    Expression* defaultInitLiteral(const Loc& loc);
    void accept(Visitor* v);
};

class TypeNext : public Type
{
public:
    Type* next;
    void checkDeprecated(const Loc& loc, Scope* sc);
    int32_t hasWild() const;
    Type* nextOf();
    Type* makeConst();
    Type* makeImmutable();
    Type* makeShared();
    Type* makeSharedConst();
    Type* makeWild();
    Type* makeWildConst();
    Type* makeSharedWild();
    Type* makeSharedWildConst();
    Type* makeMutable();
    MATCH constConv(Type* to);
    uint8_t deduceWild(Type* t, bool isRef);
    void transitive();
    void accept(Visitor* v);
};

class TypeBasic : public Type
{
public:
    char* dstring;
    uint32_t flags;
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc) /* const */;
    uint32_t alignsize();
    bool isintegral();
    bool isfloating() /* const */;
    bool isreal() /* const */;
    bool isimaginary() /* const */;
    bool iscomplex() /* const */;
    bool isscalar() /* const */;
    bool isunsigned() /* const */;
    MATCH implicitConvTo(Type* to);
    bool isZeroInit(const Loc& loc) /* const */;
    TypeBasic* isTypeBasic();
    void accept(Visitor* v);
};

class TypeVector : public Type
{
public:
    Type* basetype;
    static TypeVector* create(Type* basetype);
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc);
    uint32_t alignsize();
    bool isintegral();
    bool isfloating();
    bool isscalar();
    bool isunsigned();
    bool isBoolean() /* const */;
    MATCH implicitConvTo(Type* to);
    Expression* defaultInitLiteral(const Loc& loc);
    TypeBasic* elementType();
    bool isZeroInit(const Loc& loc);
    void accept(Visitor* v);
};

class TypeArray : public TypeNext
{
public:
    void accept(Visitor* v);
};

class TypeSArray : public TypeArray
{
public:
    Expression* dim;
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc);
    uint32_t alignsize();
    bool isString();
    bool isZeroInit(const Loc& loc);
    uint32_t alignment();
    MATCH constConv(Type* to);
    MATCH implicitConvTo(Type* to);
    Expression* defaultInitLiteral(const Loc& loc);
    bool hasPointers();
    bool needsDestruction();
    bool needsCopyOrPostblit();
    bool needsNested();
    void accept(Visitor* v);
};

class TypeDArray : public TypeArray
{
public:
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc) /* const */;
    uint32_t alignsize() /* const */;
    bool isString();
    bool isZeroInit(const Loc& loc) /* const */;
    bool isBoolean() /* const */;
    MATCH implicitConvTo(Type* to);
    bool hasPointers() /* const */;
    void accept(Visitor* v);
};

class TypeAArray : public TypeArray
{
public:
    Type* index;
    Loc loc;
    static TypeAArray* create(Type* t, Type* index);
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc) /* const */;
    bool isZeroInit(const Loc& loc) /* const */;
    bool isBoolean() /* const */;
    bool hasPointers() /* const */;
    MATCH implicitConvTo(Type* to);
    MATCH constConv(Type* to);
    void accept(Visitor* v);
};

class TypePointer : public TypeNext
{
public:
    static TypePointer* create(Type* t);
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc) /* const */;
    MATCH implicitConvTo(Type* to);
    MATCH constConv(Type* to);
    bool isscalar() /* const */;
    bool isZeroInit(const Loc& loc) /* const */;
    bool hasPointers() /* const */;
    void accept(Visitor* v);
};

class TypeReference : public TypeNext
{
public:
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc) /* const */;
    bool isZeroInit(const Loc& loc) /* const */;
    void accept(Visitor* v);
};

BEGIN_ENUM(RET, RET, ret)
    ENUM_KEY(int32_t, regs, 1, RET, RET, ret, RET)
    ENUM_KEY(int32_t, stack, 2, RET, RET, ret, RET)
END_ENUM(RET, RET, ret)

BEGIN_ENUM_NUMERIC(uint8_t, TRUST, TRUST, trust)
    ENUM_KEY_NUMERIC(uint8_t, default_, 0u, TRUST, TRUST, trust, TRUST)
    ENUM_KEY_NUMERIC(uint8_t, system, 1u, TRUST, TRUST, trust, TRUST)
    ENUM_KEY_NUMERIC(uint8_t, trusted, 2u, TRUST, TRUST, trust, TRUST)
    ENUM_KEY_NUMERIC(uint8_t, safe, 3u, TRUST, TRUST, trust, TRUST)
END_ENUM_NUMERIC(uint8_t, TRUST, TRUST, trust)

BEGIN_ENUM(TRUSTformat, TRUSTFORMAT, trustformat)
    ENUM_KEY(int32_t, TRUSTformatDefault, 0, TRUSTformat, TRUSTFORMAT, trustformat, TRUST)
    ENUM_KEY(int32_t, TRUSTformatSystem, 1, TRUSTformat, TRUSTFORMAT, trustformat, TRUST)
END_ENUM(TRUSTformat, TRUSTFORMAT, trustformat)

class TypeFunction : public TypeNext
{
public:
    ParameterList parameterList;
    BEGIN_ENUM_NUMERIC(uint32_t, FunctionFlag, FUNCTIONFLAG, functionflag)
        ENUM_KEY_NUMERIC(uint32_t, none, 0u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isnothrow, 1u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isnogc, 2u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isproperty, 4u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isref, 8u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isreturn, 16u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isscope, 32u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isreturninferred, 64u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, isscopeinferred, 128u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, islive, 256u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, incomplete, 512u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, inoutParam, 1024u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
        ENUM_KEY_NUMERIC(uint32_t, inoutQual, 2048u, FunctionFlag, FUNCTIONFLAG, functionflag, FF)
    END_ENUM_NUMERIC(uint32_t, FunctionFlag, FUNCTIONFLAG, functionflag)

    LINK linkage;
    FunctionFlag funcFlags;
    TRUST trust;
    PURE purity;
    int8_t inuse;
    Array<Expression*>* fargs;
    static TypeFunction* create(Array<Parameter*>* parameters, Type* treturn, uint8_t varargs, LINK linkage, StorageClass stc = 0);
    const char* kind() const;
    Type* syntaxCopy();
    void purityLevel();
    bool hasLazyParameters();
    bool isDstyleVariadic() const;
    bool parameterEscapes(Type* tthis, Parameter* p);
    StorageClass parameterStorageClass(Type* tthis, Parameter* p);
    Type* addStorageClass(StorageClass stc);
    Type* substWildTo(uint32_t _param_0);
    const char* getParamError(Expression* arg, Parameter* par);
    bool isnothrow() const;
    void isnothrow(bool v);
    bool isnogc() const;
    void isnogc(bool v);
    bool isproperty() const;
    void isproperty(bool v);
    bool isref() const;
    void isref(bool v);
    bool isreturn() const;
    void isreturn(bool v);
    bool isScopeQual() const;
    void isScopeQual(bool v);
    bool isreturninferred() const;
    void isreturninferred(bool v);
    bool isscopeinferred() const;
    void isscopeinferred(bool v);
    bool islive() const;
    void islive(bool v);
    bool incomplete() const;
    void incomplete(bool v);
    bool isInOutParam() const;
    void isInOutParam(bool v);
    bool isInOutQual() const;
    void isInOutQual(bool v);
    bool iswild() const;
    void accept(Visitor* v);
};

class TypeDelegate : public TypeNext
{
public:
    static TypeDelegate* create(Type* t);
    const char* kind() const;
    Type* syntaxCopy();
    Type* addStorageClass(StorageClass stc);
    d_uns64 size(const Loc& loc) /* const */;
    uint32_t alignsize() /* const */;
    MATCH implicitConvTo(Type* to);
    bool isZeroInit(const Loc& loc) /* const */;
    bool isBoolean() /* const */;
    bool hasPointers() /* const */;
    void accept(Visitor* v);
};

class TypeTraits : public Type
{
public:
    Loc loc;
    TraitsExp* exp;
    Dsymbol* sym;
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    void accept(Visitor* v);
    d_uns64 size(const Loc& loc);
};

class TypeMixin : public Type
{
public:
    Loc loc;
    Array<Expression*>* exps;
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    void accept(Visitor* v);
};

class TypeQualified : public Type
{
public:
    Loc loc;
    Array<RootObject*> idents;
    void syntaxCopyHelper(TypeQualified* t);
    void addIdent(Identifier* ident);
    void addInst(TemplateInstance* inst);
    void addIndex(RootObject* e);
    d_uns64 size(const Loc& loc);
    void accept(Visitor* v);
    ~TypeQualified();
};

class TypeIdentifier : public TypeQualified
{
public:
    Identifier* ident;
    Dsymbol* originalSymbol;
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    void accept(Visitor* v);
    ~TypeIdentifier();
};

class TypeInstance : public TypeQualified
{
public:
    TemplateInstance* tempinst;
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    void accept(Visitor* v);
    ~TypeInstance();
};

class TypeTypeof : public TypeQualified
{
public:
    Expression* exp;
    int32_t inuse;
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    d_uns64 size(const Loc& loc);
    void accept(Visitor* v);
    ~TypeTypeof();
};

class TypeReturn : public TypeQualified
{
public:
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    void accept(Visitor* v);
    ~TypeReturn();
};

BEGIN_ENUM(AliasThisRec, ALIASTHISREC, aliasthisrec)
    ENUM_KEY(int32_t, no, 0, AliasThisRec, ALIASTHISREC, aliasthisrec, ATR)
    ENUM_KEY(int32_t, yes, 1, AliasThisRec, ALIASTHISREC, aliasthisrec, ATR)
    ENUM_KEY(int32_t, fwdref, 2, AliasThisRec, ALIASTHISREC, aliasthisrec, ATR)
    ENUM_KEY(int32_t, typeMask, 3, AliasThisRec, ALIASTHISREC, aliasthisrec, ATR)
    ENUM_KEY(int32_t, tracing, 4, AliasThisRec, ALIASTHISREC, aliasthisrec, ATR)
    ENUM_KEY(int32_t, tracingDT, 8, AliasThisRec, ALIASTHISREC, aliasthisrec, ATR)
END_ENUM(AliasThisRec, ALIASTHISREC, aliasthisrec)

class TypeStruct : public Type
{
public:
    StructDeclaration* sym;
    AliasThisRec att;
    bool inuse;
    static TypeStruct* create(StructDeclaration* sym);
    const char* kind() const;
    d_uns64 size(const Loc& loc);
    uint32_t alignsize();
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    uint32_t alignment();
    Expression* defaultInitLiteral(const Loc& loc);
    bool isZeroInit(const Loc& loc);
    bool isAssignable();
    bool isBoolean() /* const */;
    bool needsDestruction() /* const */;
    bool needsCopyOrPostblit();
    bool needsNested();
    bool hasPointers();
    bool hasVoidInitPointers();
    MATCH implicitConvTo(Type* to);
    MATCH constConv(Type* to);
    uint8_t deduceWild(Type* t, bool isRef);
    Type* toHeadMutable();
    void accept(Visitor* v);
};

class TypeEnum : public Type
{
public:
    EnumDeclaration* sym;
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc);
    Type* memType(const Loc& loc);
    uint32_t alignsize();
    Dsymbol* toDsymbol(Scope* sc);
    bool isintegral();
    bool isfloating();
    bool isreal();
    bool isimaginary();
    bool iscomplex();
    bool isscalar();
    bool isunsigned();
    bool isBoolean();
    bool isString();
    bool isAssignable();
    bool needsDestruction();
    bool needsCopyOrPostblit();
    bool needsNested();
    MATCH implicitConvTo(Type* to);
    MATCH constConv(Type* to);
    bool isZeroInit(const Loc& loc);
    bool hasPointers();
    bool hasVoidInitPointers();
    Type* nextOf();
    void accept(Visitor* v);
};

class TypeClass : public Type
{
public:
    ClassDeclaration* sym;
    AliasThisRec att;
    CPPMANGLE cppmangle;
    const char* kind() const;
    d_uns64 size(const Loc& loc) /* const */;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    ClassDeclaration* isClassHandle();
    bool isBaseOf(Type* t, int32_t* poffset);
    MATCH implicitConvTo(Type* to);
    MATCH constConv(Type* to);
    uint8_t deduceWild(Type* t, bool isRef);
    Type* toHeadMutable();
    bool isZeroInit(const Loc& loc) /* const */;
    bool isscope() /* const */;
    bool isBoolean() /* const */;
    bool hasPointers() /* const */;
    void accept(Visitor* v);
};

class TypeTuple : public Type
{
public:
    static TypeTuple* empty;
    Array<Parameter*>* arguments;
    static TypeTuple* create(Array<Parameter*>* arguments);
    static TypeTuple* create();
    static TypeTuple* create(Type* t1);
    static TypeTuple* create(Type* t1, Type* t2);
    const char* kind() const;
    Type* syntaxCopy();
    bool equals(const RootObject* const o) const;
    void accept(Visitor* v);
};

class TypeSlice : public TypeNext
{
public:
    Expression* lwr;
    Expression* upr;
    const char* kind() const;
    Type* syntaxCopy();
    void accept(Visitor* v);
};

class TypeNull : public Type
{
public:
    const char* kind() const;
    Type* syntaxCopy();
    MATCH implicitConvTo(Type* to);
    bool hasPointers();
    bool isBoolean() /* const */;
    d_uns64 size(const Loc& loc) /* const */;
    void accept(Visitor* v);
};

class Parameter : public ASTNode
{
public:
    StorageClass storageClass;
    Type* type;
    Identifier* ident;
    Expression* defaultArg;
    UserAttributeDeclaration* userAttribDecl;
    static Parameter* create(StorageClass storageClass, Type* type, Identifier* ident, Expression* defaultArg, UserAttributeDeclaration* userAttribDecl);
    Parameter* syntaxCopy();
    Type* isLazyArray();
    bool isReference() const;
    DYNCAST dyncast() const;
    void accept(Visitor* v);
    static size_t dim(Array<Parameter*>* parameters);
    static Parameter* getNth(Array<Parameter*>* parameters, size_t nth);
    const char* toChars() const;
    bool isCovariant(bool returnByRef, const Parameter* const p, bool previewIn) const;
    BEGIN_ENUM(SR, SR, sr)
        ENUM_KEY(int32_t, None, 0, SR, SR, sr, SR)
        ENUM_KEY(int32_t, Scope, 1, SR, SR, sr, SR)
        ENUM_KEY(int32_t, ReturnScope, 2, SR, SR, sr, SR)
        ENUM_KEY(int32_t, Ref, 3, SR, SR, sr, SR)
        ENUM_KEY(int32_t, ReturnRef, 4, SR, SR, sr, SR)
        ENUM_KEY(int32_t, RefScope, 5, SR, SR, sr, SR)
        ENUM_KEY(int32_t, ReturnRef_Scope, 6, SR, SR, sr, SR)
        ENUM_KEY(int32_t, Ref_ReturnScope, 7, SR, SR, sr, SR)
    END_ENUM(SR, SR, sr)

};

extern AggregateDeclaration* isAggregate(Type* t);

class NOGCVisitor : public StoppableVisitor
{
public:
    FuncDeclaration* f;
    bool err;
    void doCond(Expression* exp);
    void visit(Expression* e);
    void visit(DeclarationExp* e);
    void visit(CallExp* e);
    void visit(ArrayLiteralExp* e);
    void visit(AssocArrayLiteralExp* e);
    void visit(NewExp* e);
    void visit(DeleteExp* e);
    void visit(IndexExp* e);
    void visit(AssignExp* e);
    void visit(CatAssignExp* e);
    void visit(CatExp* e);
};

class Nspace : public ScopeDsymbol
{
public:
    Expression* identExp;
    Dsymbol* syntaxCopy(Dsymbol* s);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    void setScope(Scope* sc);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    bool hasPointers();
    void setFieldOffset(AggregateDeclaration* ad, uint32_t* poffset, bool isunion);
    const char* kind() const;
    Nspace* isNspace();
    void accept(Visitor* v);
    ~Nspace();
};

typedef Array<ObNode*> ObNodes;

typedef StmtState<ObNode> StmtState;

BEGIN_ENUM_NUMERIC(uint8_t, ObType, OBTYPE, obtype)
    ENUM_KEY_NUMERIC(uint8_t, goto_, 0u, ObType, OBTYPE, obtype, OT)
    ENUM_KEY_NUMERIC(uint8_t, return_, 1u, ObType, OBTYPE, obtype, OT)
    ENUM_KEY_NUMERIC(uint8_t, retexp, 2u, ObType, OBTYPE, obtype, OT)
    ENUM_KEY_NUMERIC(uint8_t, throw_, 3u, ObType, OBTYPE, obtype, OT)
    ENUM_KEY_NUMERIC(uint8_t, exit, 4u, ObType, OBTYPE, obtype, OT)
    ENUM_KEY_NUMERIC(uint8_t, try_, 5u, ObType, OBTYPE, obtype, OT)
    ENUM_KEY_NUMERIC(uint8_t, finally_, 6u, ObType, OBTYPE, obtype, OT)
    ENUM_KEY_NUMERIC(uint8_t, fend, 7u, ObType, OBTYPE, obtype, OT)
END_ENUM_NUMERIC(uint8_t, ObType, OBTYPE, obtype)

BEGIN_ENUM_NUMERIC(uint8_t, PtrState, PTRSTATE, ptrstate)
    ENUM_KEY_NUMERIC(uint8_t, Initial, 0u, PtrState, PTRSTATE, ptrstate, PS)
    ENUM_KEY_NUMERIC(uint8_t, Undefined, 1u, PtrState, PTRSTATE, ptrstate, PS)
    ENUM_KEY_NUMERIC(uint8_t, Owner, 2u, PtrState, PTRSTATE, ptrstate, PS)
    ENUM_KEY_NUMERIC(uint8_t, Borrowed, 3u, PtrState, PTRSTATE, ptrstate, PS)
    ENUM_KEY_NUMERIC(uint8_t, Readonly, 4u, PtrState, PTRSTATE, ptrstate, PS)
END_ENUM_NUMERIC(uint8_t, PtrState, PTRSTATE, ptrstate)

class Objc
{
public:
    static void _init();
    static void deinitialize();
    virtual void setObjc(ClassDeclaration* cd) = 0;
    virtual void setObjc(InterfaceDeclaration* ) = 0;
    virtual void deprecate(InterfaceDeclaration* interfaceDeclaration) const = 0;
    virtual void setSelector(FuncDeclaration* , Scope* sc) = 0;
    virtual void validateSelector(FuncDeclaration* fd) = 0;
    virtual void checkLinkage(FuncDeclaration* fd) = 0;
    virtual bool isVirtual(const FuncDeclaration* const fd) const = 0;
    virtual ClassDeclaration* getParent(FuncDeclaration* fd, ClassDeclaration* cd) const = 0;
    virtual void addToClassMethodList(FuncDeclaration* fd, ClassDeclaration* cd) const = 0;
    virtual AggregateDeclaration* isThis(FuncDeclaration* funcDeclaration) const = 0;
    virtual VarDeclaration* createSelectorParameter(FuncDeclaration* fd, Scope* sc) const = 0;
    virtual void setMetaclass(InterfaceDeclaration* interfaceDeclaration, Scope* sc) const = 0;
    virtual void setMetaclass(ClassDeclaration* classDeclaration, Scope* sc) const = 0;
    virtual ClassDeclaration* getRuntimeMetaclass(ClassDeclaration* classDeclaration) const = 0;
    virtual void addSymbols(AttribDeclaration* attribDeclaration, Array<ClassDeclaration*>* classes, Array<ClassDeclaration*>* categories) const = 0;
    virtual void addSymbols(ClassDeclaration* classDeclaration, Array<ClassDeclaration*>* classes, Array<ClassDeclaration*>* categories) const = 0;
    virtual void checkOffsetof(Expression* expression, AggregateDeclaration* aggregateDeclaration) const = 0;
    virtual void checkTupleof(Expression* expression, TypeClass* type) const = 0;
};

BEGIN_ENUM(ParseStatementFlags, PARSESTATEMENTFLAGS, parsestatementflags)
    ENUM_KEY(int32_t, semi, 1, ParseStatementFlags, PARSESTATEMENTFLAGS, parsestatementflags, PSF)
    ENUM_KEY(int32_t, scope_, 2, ParseStatementFlags, PARSESTATEMENTFLAGS, parsestatementflags, PSF)
    ENUM_KEY(int32_t, curly, 4, ParseStatementFlags, PARSESTATEMENTFLAGS, parsestatementflags, PSF)
    ENUM_KEY(int32_t, curlyScope, 8, ParseStatementFlags, PARSESTATEMENTFLAGS, parsestatementflags, PSF)
    ENUM_KEY(int32_t, semiOk, 16, ParseStatementFlags, PARSESTATEMENTFLAGS, parsestatementflags, PSF)
END_ENUM(ParseStatementFlags, PARSESTATEMENTFLAGS, parsestatementflags)

BEGIN_ENUM(PREC, PREC, prec)
    ENUM_KEY(int32_t, zero, 0, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, expr, 1, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, assign, 2, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, cond, 3, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, oror, 4, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, andand, 5, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, or, 6, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, xor, 7, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, and, 8, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, equal, 9, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, rel, 10, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, shift, 11, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, add, 12, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, mul, 13, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, pow, 14, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, unary, 15, PREC, PREC, prec, PREC)
    ENUM_KEY(int32_t, primary, 16, PREC, PREC, prec, PREC)
END_ENUM(PREC, PREC, prec)

class PostorderStatementVisitor : public StoppableVisitor
{
public:
    StoppableVisitor* v;
    bool doCond(Statement* s);
    bool applyTo(Statement* s);
    void visit(Statement* s);
    void visit(PeelStatement* s);
    void visit(CompoundStatement* s);
    void visit(UnrolledLoopStatement* s);
    void visit(ScopeStatement* s);
    void visit(WhileStatement* s);
    void visit(DoStatement* s);
    void visit(ForStatement* s);
    void visit(ForeachStatement* s);
    void visit(ForeachRangeStatement* s);
    void visit(IfStatement* s);
    void visit(PragmaStatement* s);
    void visit(SwitchStatement* s);
    void visit(CaseStatement* s);
    void visit(DefaultStatement* s);
    void visit(SynchronizedStatement* s);
    void visit(WithStatement* s);
    void visit(TryCatchStatement* s);
    void visit(TryFinallyStatement* s);
    void visit(ScopeGuardStatement* s);
    void visit(DebugStatement* s);
    void visit(LabelStatement* s);
};

ENUM_CONSTANT_NUMERIC(bool, LOG, false)

ENUM_CONSTANT_NUMERIC(bool, LOG, false)

extern void semantic2(Dsymbol* dsym, Scope* sc);

ENUM_CONSTANT_NUMERIC(bool, LOG, false)

extern void semantic3(Dsymbol* dsym, Scope* sc);

extern bool isTrivialExp(Expression* e);

extern bool hasSideEffect(Expression* e);

BEGIN_ENUM_NUMERIC(uint8_t, STMT, STMT, stmt)
    ENUM_KEY_NUMERIC(uint8_t, Error, 0u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Peel, 1u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Exp, 2u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, DtorExp, 3u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Compile, 4u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Compound, 5u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, CompoundDeclaration, 6u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, CompoundAsm, 7u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, UnrolledLoop, 8u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Scope, 9u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Forwarding, 10u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, While, 11u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Do, 12u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, For, 13u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Foreach, 14u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, ForeachRange, 15u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, If, 16u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Conditional, 17u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, StaticForeach, 18u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Pragma, 19u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, StaticAssert, 20u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Switch, 21u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Case, 22u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, CaseRange, 23u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Default, 24u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, GotoDefault, 25u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, GotoCase, 26u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, SwitchError, 27u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Return, 28u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Break, 29u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Continue, 30u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Synchronized, 31u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, With, 32u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, TryCatch, 33u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, TryFinally, 34u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, ScopeGuard, 35u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Throw, 36u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Debug, 37u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Goto, 38u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Label, 39u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Asm, 40u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, InlineAsm, 41u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, GccAsm, 42u, STMT, STMT, stmt, STMT)
    ENUM_KEY_NUMERIC(uint8_t, Import, 43u, STMT, STMT, stmt, STMT)
END_ENUM_NUMERIC(uint8_t, STMT, STMT, stmt)

class Statement : public ASTNode
{
public:
    Loc loc;
    STMT stmt;
    DYNCAST dyncast() const;
    virtual Statement* syntaxCopy();
    static Array<Statement*>* arraySyntaxCopy(Array<Statement*>* a);
    const char* toChars() const;
    void error(const char* format, ...);
    void warning(const char* format, ...);
    void deprecation(const char* format, ...);
    virtual Statement* getRelatedLabeled();
    virtual bool hasBreak() const;
    virtual bool hasContinue() const;
    bool usesEH();
    bool comeFrom();
    bool hasCode();
    virtual Statement* scopeCode(Scope* sc, Statement** sentry, Statement** sexception, Statement** sfinally);
    virtual Array<Statement*>* flatten(Scope* sc);
    virtual Statement* last();
    void accept(Visitor* v);
    virtual ReturnStatement* endsWithReturnStatement();
    ErrorStatement* isErrorStatement();
    ScopeStatement* isScopeStatement();
    ExpStatement* isExpStatement();
    CompoundStatement* isCompoundStatement();
    ReturnStatement* isReturnStatement();
    IfStatement* isIfStatement();
    CaseStatement* isCaseStatement();
    DefaultStatement* isDefaultStatement();
    LabelStatement* isLabelStatement();
    GotoStatement* isGotoStatement();
    GotoDefaultStatement* isGotoDefaultStatement();
    GotoCaseStatement* isGotoCaseStatement();
    BreakStatement* isBreakStatement();
    DtorExpStatement* isDtorExpStatement();
    ForwardingStatement* isForwardingStatement();
    DoStatement* isDoStatement();
    WhileStatement* isWhileStatement();
    ForStatement* isForStatement();
    ForeachStatement* isForeachStatement();
    SwitchStatement* isSwitchStatement();
    ContinueStatement* isContinueStatement();
    WithStatement* isWithStatement();
    TryCatchStatement* isTryCatchStatement();
    ThrowStatement* isThrowStatement();
    TryFinallyStatement* isTryFinallyStatement();
    SwitchErrorStatement* isSwitchErrorStatement();
    UnrolledLoopStatement* isUnrolledLoopStatement();
    ForeachRangeStatement* isForeachRangeStatement();
    CompoundDeclarationStatement* isCompoundDeclarationStatement();
};

class ErrorStatement : public Statement
{
public:
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class PeelStatement : public Statement
{
public:
    Statement* s;
    void accept(Visitor* v);
};

class ExpStatement : public Statement
{
public:
    Expression* exp;
    static ExpStatement* create(Loc loc, Expression* exp);
    Statement* syntaxCopy();
    Statement* scopeCode(Scope* sc, Statement** sentry, Statement** sexception, Statement** sfinally);
    Array<Statement*>* flatten(Scope* sc);
    void accept(Visitor* v);
};

class DtorExpStatement : public ExpStatement
{
public:
    VarDeclaration* var;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class CompileStatement : public Statement
{
public:
    Array<Expression*>* exps;
    Statement* syntaxCopy();
    Array<Statement*>* compileIt(Scope* sc);
    Array<Statement*>* flatten(Scope* sc);
    void accept(Visitor* v);
};

class CompoundStatement : public Statement
{
public:
    Array<Statement*>* statements;
    static CompoundStatement* create(Loc loc, Statement* s1, Statement* s2);
    Statement* syntaxCopy();
    Array<Statement*>* flatten(Scope* sc);
    ReturnStatement* endsWithReturnStatement();
    Statement* last();
    void accept(Visitor* v);
};

class CompoundDeclarationStatement : public CompoundStatement
{
public:
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class UnrolledLoopStatement : public Statement
{
public:
    Array<Statement*>* statements;
    Statement* syntaxCopy();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class ScopeStatement : public Statement
{
public:
    Statement* statement;
    Loc endloc;
    Statement* syntaxCopy();
    ReturnStatement* endsWithReturnStatement();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class ForwardingStatement : public Statement
{
public:
    ForwardingScopeDsymbol* sym;
    Statement* statement;
    Statement* syntaxCopy();
    Array<Statement*>* flatten(Scope* sc);
    void accept(Visitor* v);
};

class WhileStatement : public Statement
{
public:
    Expression* condition;
    Statement* _body;
    Loc endloc;
    Statement* syntaxCopy();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class DoStatement : public Statement
{
public:
    Statement* _body;
    Expression* condition;
    Loc endloc;
    Statement* syntaxCopy();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class ForStatement : public Statement
{
public:
    Statement* _init;
    Expression* condition;
    Expression* increment;
    Statement* _body;
    Loc endloc;
    Statement* relatedLabeled;
    Statement* syntaxCopy();
    Statement* scopeCode(Scope* sc, Statement** sentry, Statement** sexception, Statement** sfinally);
    Statement* getRelatedLabeled();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class ForeachStatement : public Statement
{
public:
    TOK op;
    Array<Parameter*>* parameters;
    Expression* aggr;
    Statement* _body;
    Loc endloc;
    VarDeclaration* key;
    VarDeclaration* value;
    FuncDeclaration* func;
    Array<Statement*>* cases;
    Array<ScopeStatement*>* gotos;
    Statement* syntaxCopy();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class ForeachRangeStatement : public Statement
{
public:
    TOK op;
    Parameter* prm;
    Expression* lwr;
    Expression* upr;
    Statement* _body;
    Loc endloc;
    VarDeclaration* key;
    Statement* syntaxCopy();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class IfStatement : public Statement
{
public:
    Parameter* prm;
    Expression* condition;
    Statement* ifbody;
    Statement* elsebody;
    VarDeclaration* match;
    Loc endloc;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class ConditionalStatement : public Statement
{
public:
    Condition* condition;
    Statement* ifbody;
    Statement* elsebody;
    Statement* syntaxCopy();
    Array<Statement*>* flatten(Scope* sc);
    void accept(Visitor* v);
};

class StaticForeachStatement : public Statement
{
public:
    StaticForeach* sfe;
    Statement* syntaxCopy();
    Array<Statement*>* flatten(Scope* sc);
    void accept(Visitor* v);
};

class PragmaStatement : public Statement
{
public:
    Identifier* ident;
    Array<Expression*>* args;
    Statement* _body;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class StaticAssertStatement : public Statement
{
public:
    StaticAssert* sa;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class SwitchStatement : public Statement
{
public:
    Expression* condition;
    Statement* _body;
    bool isFinal;
    DefaultStatement* sdefault;
    Statement* tryBody;
    TryFinallyStatement* tf;
    Array<GotoCaseStatement*> gotoCases;
    Array<CaseStatement*>* cases;
    int32_t hasNoDefault;
    int32_t hasVars;
    VarDeclaration* lastVar;
    Statement* syntaxCopy();
    bool hasBreak() const;
    void accept(Visitor* v);
    ~SwitchStatement();
};

class CaseStatement : public Statement
{
public:
    Expression* exp;
    Statement* statement;
    int32_t index;
    VarDeclaration* lastVar;
    void* extra;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class CaseRangeStatement : public Statement
{
public:
    Expression* first;
    Expression* last;
    Statement* statement;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class DefaultStatement : public Statement
{
public:
    Statement* statement;
    VarDeclaration* lastVar;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class GotoDefaultStatement : public Statement
{
public:
    SwitchStatement* sw;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class GotoCaseStatement : public Statement
{
public:
    Expression* exp;
    CaseStatement* cs;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class SwitchErrorStatement : public Statement
{
public:
    Expression* exp;
    void accept(Visitor* v);
};

class ReturnStatement : public Statement
{
public:
    Expression* exp;
    size_t caseDim;
    Statement* syntaxCopy();
    ReturnStatement* endsWithReturnStatement();
    void accept(Visitor* v);
};

class BreakStatement : public Statement
{
public:
    Identifier* ident;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class ContinueStatement : public Statement
{
public:
    Identifier* ident;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class SynchronizedStatement : public Statement
{
public:
    Expression* exp;
    Statement* _body;
    Statement* syntaxCopy();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class WithStatement : public Statement
{
public:
    Expression* exp;
    Statement* _body;
    VarDeclaration* wthis;
    Loc endloc;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class TryCatchStatement : public Statement
{
public:
    Statement* _body;
    Array<Catch*>* catches;
    Statement* tryBody;
    Statement* syntaxCopy();
    bool hasBreak() const;
    void accept(Visitor* v);
};

class Catch : public RootObject
{
public:
    Loc loc;
    Type* type;
    Identifier* ident;
    Statement* handler;
    VarDeclaration* var;
    bool errors;
    bool internalCatch;
    Catch* syntaxCopy();
};

class TryFinallyStatement : public Statement
{
public:
    Statement* _body;
    Statement* finalbody;
    Statement* tryBody;
    bool bodyFallsThru;
    static TryFinallyStatement* create(Loc loc, Statement* _body, Statement* finalbody);
    Statement* syntaxCopy();
    bool hasBreak() const;
    bool hasContinue() const;
    void accept(Visitor* v);
};

class ScopeGuardStatement : public Statement
{
public:
    TOK tok;
    Statement* statement;
    Statement* syntaxCopy();
    Statement* scopeCode(Scope* sc, Statement** sentry, Statement** sexception, Statement** sfinally);
    void accept(Visitor* v);
};

class ThrowStatement : public Statement
{
public:
    Expression* exp;
    bool internalThrow;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class DebugStatement : public Statement
{
public:
    Statement* statement;
    Statement* syntaxCopy();
    Array<Statement*>* flatten(Scope* sc);
    void accept(Visitor* v);
};

class GotoStatement : public Statement
{
public:
    Identifier* ident;
    LabelDsymbol* label;
    Statement* tryBody;
    TryFinallyStatement* tf;
    ScopeGuardStatement* os;
    VarDeclaration* lastVar;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class LabelStatement : public Statement
{
public:
    Identifier* ident;
    Statement* statement;
    Statement* tryBody;
    TryFinallyStatement* tf;
    ScopeGuardStatement* os;
    VarDeclaration* lastVar;
    Statement* gotoTarget;
    void* extra;
    bool breaks;
    Statement* syntaxCopy();
    Array<Statement*>* flatten(Scope* sc);
    Statement* scopeCode(Scope* sc, Statement** sentry, Statement** sexit, Statement** sfinally);
    void accept(Visitor* v);
};

class LabelDsymbol : public Dsymbol
{
public:
    LabelStatement* statement;
    bool deleted;
    bool iasm;
    static LabelDsymbol* create(Identifier* ident);
    LabelDsymbol* isLabel();
    void accept(Visitor* v);
};

class AsmStatement : public Statement
{
public:
    Token* tokens;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class InlineAsmStatement : public AsmStatement
{
public:
    code* asmcode;
    uint32_t asmalign;
    uint32_t regs;
    bool refparam;
    bool naked;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class GccAsmStatement : public AsmStatement
{
public:
    StorageClass stc;
    Expression* insn;
    Array<Expression*>* args;
    uint32_t outputargs;
    Array<Identifier*>* names;
    Array<Expression*>* constraints;
    Array<Expression*>* clobbers;
    Array<Identifier*>* labels;
    Array<GotoStatement*>* gotos;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class CompoundAsmStatement : public CompoundStatement
{
public:
    StorageClass stc;
    CompoundAsmStatement* syntaxCopy();
    Array<Statement*>* flatten(Scope* sc);
    void accept(Visitor* v);
};

class ImportStatement : public Statement
{
public:
    Array<Dsymbol*>* imports;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

extern Statement* statementSemantic(Statement* s, Scope* sc);

class StaticAssert : public Dsymbol
{
public:
    Expression* exp;
    Expression* msg;
    Dsymbol* syntaxCopy(Dsymbol* s);
    void addMember(Scope* sc, ScopeDsymbol* sds);
    bool oneMember(Dsymbol** ps, Identifier* ident);
    const char* kind() const;
    void accept(Visitor* v);
};

struct Target
{
    uint32_t ptrsize;
    uint32_t realsize;
    uint32_t realpad;
    uint32_t realalignsize;
    uint32_t classinfosize;
    uint64_t maxStaticDataSize;
    TargetC c;
    TargetCPP cpp;
    TargetObjC objc;
    DArray< const char > architectureName;
    template <typename T>
    struct FPTypeProperties
    {
        // Ignoring var max alignment 0
        real_t max;
        // Ignoring var min_normal alignment 0
        real_t min_normal;
        // Ignoring var nan alignment 0
        real_t nan;
        // Ignoring var infinity alignment 0
        real_t infinity;
        // Ignoring var epsilon alignment 0
        real_t epsilon;
        // Ignoring var dig alignment 0
        d_int64 dig;
        // Ignoring var mant_dig alignment 0
        d_int64 mant_dig;
        // Ignoring var max_exp alignment 0
        d_int64 max_exp;
        // Ignoring var min_exp alignment 0
        d_int64 min_exp;
        // Ignoring var max_10_exp alignment 0
        d_int64 max_10_exp;
        // Ignoring var min_10_exp alignment 0
        d_int64 min_10_exp;
    };

    FPTypeProperties<float> FloatProperties;
    FPTypeProperties<double> DoubleProperties;
    FPTypeProperties<_d_real> RealProperties;
    Type* tvalist;
    void _init(const Param& params);
    void deinitialize();
    uint32_t alignsize(Type* type);
    uint32_t fieldalign(Type* type);
    uint32_t critsecsize();
    Type* va_listType(const Loc& loc, Scope* sc);
    int32_t isVectorTypeSupported(int32_t sz, Type* type);
    bool isVectorOpSupported(Type* type, uint8_t op, Type* t2);
    LINK systemLinkage();
    TypeTuple* toArgTypes(Type* t);
    bool isReturnOnStack(TypeFunction* tf, bool needsThis);
    uint64_t parameterSize(const Loc& loc, Type* t);
    void applyInRefParams(TypeFunction* tf);
    BEGIN_ENUM(TargetInfoKeys, TARGETINFOKEYS, targetinfokeys)
        ENUM_KEY(int32_t, cppRuntimeLibrary, 0, TargetInfoKeys, TARGETINFOKEYS, targetinfokeys, TIK)
        ENUM_KEY(int32_t, cppStd, 1, TargetInfoKeys, TARGETINFOKEYS, targetinfokeys, TIK)
        ENUM_KEY(int32_t, floatAbi, 2, TargetInfoKeys, TARGETINFOKEYS, targetinfokeys, TIK)
        ENUM_KEY(int32_t, objectFormat, 3, TargetInfoKeys, TARGETINFOKEYS, targetinfokeys, TIK)
    END_ENUM(TargetInfoKeys, TARGETINFOKEYS, targetinfokeys)

    Expression* getTargetInfo(const char* name, const Loc& loc);
    Target() :
        ptrsize(),
        realsize(),
        realpad(),
        realalignsize(),
        classinfosize(),
        maxStaticDataSize(),
        c(),
        cpp(),
        objc(),
        architectureName(),
        FloatProperties(),
        DoubleProperties(),
        RealProperties()
    {
    }
};

extern Target target;

extern bool tpsemantic(TemplateParameter* tp, Scope* sc, Array<TemplateParameter*>* parameters);

ENUM_CONSTANT_NUMERIC(bool, LOGSEMANTIC, false)

extern Type* typeSemantic(Type* type, const Loc& loc, Scope* sc);

extern Type* getTypeInfoType(Loc loc, Type* t, Scope* sc);

class SemanticTimeTransitiveVisitor : public SemanticTimePermissiveVisitor
{
public:
    void visit(PeelStatement* s);
    void visit(UnrolledLoopStatement* s);
    void visit(DebugStatement* s);
    void visit(ForwardingStatement* s);
    void visit(StructLiteralExp* e);
    void visit(DotTemplateExp* e);
    void visit(DotVarExp* e);
    void visit(DelegateExp* e);
    void visit(DotTypeExp* e);
    void visit(VectorExp* e);
    void visit(VectorArrayExp* e);
    void visit(SliceExp* e);
    void visit(ArrayLengthExp* e);
    void visit(DelegatePtrExp* e);
    void visit(DelegateFuncptrExp* e);
    void visit(DotExp* e);
    void visit(IndexExp* e);
    void visit(RemoveExp* e);
};

typedef void* Key;

typedef void* Value;

typedef KeyValueTemplate<void*, void*> KeyValue;

typedef _d_real longdouble;

extern void browse(const char* url);

BEGIN_ENUM(Color, COLOR, color)
    ENUM_KEY(int32_t, black, 0, Color, COLOR, color, C)
    ENUM_KEY(int32_t, red, 1, Color, COLOR, color, C)
    ENUM_KEY(int32_t, green, 2, Color, COLOR, color, C)
    ENUM_KEY(int32_t, blue, 4, Color, COLOR, color, C)
    ENUM_KEY(int32_t, yellow, 3, Color, COLOR, color, C)
    ENUM_KEY(int32_t, magenta, 5, Color, COLOR, color, C)
    ENUM_KEY(int32_t, cyan, 6, Color, COLOR, color, C)
    ENUM_KEY(int32_t, lightGray, 7, Color, COLOR, color, C)
    ENUM_KEY(int32_t, bright, 8, Color, COLOR, color, C)
    ENUM_KEY(int32_t, darkGray, 8, Color, COLOR, color, C)
    ENUM_KEY(int32_t, brightRed, 9, Color, COLOR, color, C)
    ENUM_KEY(int32_t, brightGreen, 10, Color, COLOR, color, C)
    ENUM_KEY(int32_t, brightBlue, 12, Color, COLOR, color, C)
    ENUM_KEY(int32_t, brightYellow, 11, Color, COLOR, color, C)
    ENUM_KEY(int32_t, brightMagenta, 13, Color, COLOR, color, C)
    ENUM_KEY(int32_t, brightCyan, 14, Color, COLOR, color, C)
    ENUM_KEY(int32_t, white, 15, Color, COLOR, color, C)
END_ENUM(Color, COLOR, color)

BEGIN_ENUM_TYPE(Color, Classification, CLASSIFICATION, classification)
    ENUM_KEY_TYPE(Color, error, (Classification)(Color)9, Classification, CLASSIFICATION, classification, C)
    ENUM_KEY_TYPE(Color, gagged, (Classification)(Color)12, Classification, CLASSIFICATION, classification, C)
    ENUM_KEY_TYPE(Color, warning, (Classification)(Color)11, Classification, CLASSIFICATION, classification, C)
    ENUM_KEY_TYPE(Color, deprecation, (Classification)(Color)14, Classification, CLASSIFICATION, classification, C)
    ENUM_KEY_TYPE(Color, tip, (Classification)(Color)10, Classification, CLASSIFICATION, classification, C)
END_ENUM_TYPE(Color, Classification, CLASSIFICATION, classification)

extern void error(const Loc& loc, const char* format, ...);

extern void error(const char* filename, uint32_t linnum, uint32_t charnum, const char* format, ...);

extern void errorSupplemental(const Loc& loc, const char* format, ...);

extern void warning(const Loc& loc, const char* format, ...);

extern void warningSupplemental(const Loc& loc, const char* format, ...);

extern void deprecation(const Loc& loc, const char* format, ...);

extern void deprecationSupplemental(const Loc& loc, const char* format, ...);

extern void message(const Loc& loc, const char* format, ...);

extern void message(const char* format, ...);

extern void tip(const char* format, ...);

extern void verror(const Loc& loc, const char* format, va_list ap, const char* p1, const char* p2, const char* header = "Error: ");

extern void verrorSupplemental(const Loc& loc, const char* format, va_list ap);

extern void vwarning(const Loc& loc, const char* format, va_list ap);

extern void vwarningSupplemental(const Loc& loc, const char* format, va_list ap);

extern void vdeprecation(const Loc& loc, const char* format, va_list ap, const char* p1, const char* p2);

extern void vmessage(const Loc& loc, const char* format, va_list ap);

extern void vtip(const char* format, va_list ap);

extern void vdeprecationSupplemental(const Loc& loc, const char* format, va_list ap);

extern void fatal();

extern void halt();

BEGIN_ENUM_NUMERIC(uint8_t, HIGHLIGHT, HIGHLIGHT, highlight)
    ENUM_KEY_NUMERIC(uint8_t, Default, 0u, HIGHLIGHT, HIGHLIGHT, highlight, HIGHLIGHT)
    ENUM_KEY_NUMERIC(uint8_t, Escape, 255u, HIGHLIGHT, HIGHLIGHT, highlight, HIGHLIGHT)
    ENUM_KEY_NUMERIC(uint8_t, Identifier, 15u, HIGHLIGHT, HIGHLIGHT, highlight, HIGHLIGHT)
    ENUM_KEY_NUMERIC(uint8_t, Keyword, 15u, HIGHLIGHT, HIGHLIGHT, highlight, HIGHLIGHT)
    ENUM_KEY_NUMERIC(uint8_t, Literal, 15u, HIGHLIGHT, HIGHLIGHT, highlight, HIGHLIGHT)
    ENUM_KEY_NUMERIC(uint8_t, Comment, 8u, HIGHLIGHT, HIGHLIGHT, highlight, HIGHLIGHT)
    ENUM_KEY_NUMERIC(uint8_t, Other, 6u, HIGHLIGHT, HIGHLIGHT, highlight, HIGHLIGHT)
END_ENUM_NUMERIC(uint8_t, HIGHLIGHT, HIGHLIGHT, highlight)

BEGIN_ENUM_NUMERIC(bool, TARGET, TARGET, target)
    ENUM_KEY_NUMERIC(bool, Linux, true, TARGET, TARGET, target, TARGET)
    ENUM_KEY_NUMERIC(bool, OSX, false, TARGET, TARGET, target, TARGET)
    ENUM_KEY_NUMERIC(bool, FreeBSD, false, TARGET, TARGET, target, TARGET)
    ENUM_KEY_NUMERIC(bool, OpenBSD, false, TARGET, TARGET, target, TARGET)
    ENUM_KEY_NUMERIC(bool, Solaris, false, TARGET, TARGET, target, TARGET)
    ENUM_KEY_NUMERIC(bool, Windows, false, TARGET, TARGET, target, TARGET)
    ENUM_KEY_NUMERIC(bool, DragonFlyBSD, false, TARGET, TARGET, target, TARGET)
END_ENUM_NUMERIC(bool, TARGET, TARGET, target)

BEGIN_ENUM_NUMERIC(uint8_t, DiagnosticReporting, DIAGNOSTICREPORTING, diagnosticreporting)
    ENUM_KEY_NUMERIC(uint8_t, error, 0u, DiagnosticReporting, DIAGNOSTICREPORTING, diagnosticreporting, DR)
    ENUM_KEY_NUMERIC(uint8_t, inform, 1u, DiagnosticReporting, DIAGNOSTICREPORTING, diagnosticreporting, DR)
    ENUM_KEY_NUMERIC(uint8_t, off, 2u, DiagnosticReporting, DIAGNOSTICREPORTING, diagnosticreporting, DR)
END_ENUM_NUMERIC(uint8_t, DiagnosticReporting, DIAGNOSTICREPORTING, diagnosticreporting)

BEGIN_ENUM_NUMERIC(uint8_t, MessageStyle, MESSAGESTYLE, messagestyle)
    ENUM_KEY_NUMERIC(uint8_t, digitalmars, 0u, MessageStyle, MESSAGESTYLE, messagestyle, MS)
    ENUM_KEY_NUMERIC(uint8_t, gnu, 1u, MessageStyle, MESSAGESTYLE, messagestyle, MS)
END_ENUM_NUMERIC(uint8_t, MessageStyle, MESSAGESTYLE, messagestyle)

BEGIN_ENUM_NUMERIC(uint8_t, CHECKENABLE, CHECKENABLE, checkenable)
    ENUM_KEY_NUMERIC(uint8_t, _default, 0u, CHECKENABLE, CHECKENABLE, checkenable, CHECKENABLE)
    ENUM_KEY_NUMERIC(uint8_t, off, 1u, CHECKENABLE, CHECKENABLE, checkenable, CHECKENABLE)
    ENUM_KEY_NUMERIC(uint8_t, on, 2u, CHECKENABLE, CHECKENABLE, checkenable, CHECKENABLE)
    ENUM_KEY_NUMERIC(uint8_t, safeonly, 3u, CHECKENABLE, CHECKENABLE, checkenable, CHECKENABLE)
END_ENUM_NUMERIC(uint8_t, CHECKENABLE, CHECKENABLE, checkenable)

BEGIN_ENUM_NUMERIC(uint8_t, CHECKACTION, CHECKACTION, checkaction)
    ENUM_KEY_NUMERIC(uint8_t, D, 0u, CHECKACTION, CHECKACTION, checkaction, CHECKACTION)
    ENUM_KEY_NUMERIC(uint8_t, C, 1u, CHECKACTION, CHECKACTION, checkaction, CHECKACTION)
    ENUM_KEY_NUMERIC(uint8_t, halt, 2u, CHECKACTION, CHECKACTION, checkaction, CHECKACTION)
    ENUM_KEY_NUMERIC(uint8_t, context, 3u, CHECKACTION, CHECKACTION, checkaction, CHECKACTION)
END_ENUM_NUMERIC(uint8_t, CHECKACTION, CHECKACTION, checkaction)

BEGIN_ENUM(CPU, CPU, cpu)
    ENUM_KEY(int32_t, x87, 0, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, mmx, 1, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, sse, 2, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, sse2, 3, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, sse3, 4, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, ssse3, 5, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, sse4_1, 6, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, sse4_2, 7, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, avx, 8, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, avx2, 9, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, avx512, 10, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, baseline, 11, CPU, CPU, cpu, CPU)
    ENUM_KEY(int32_t, native, 12, CPU, CPU, cpu, CPU)
END_ENUM(CPU, CPU, cpu)

BEGIN_ENUM_NUMERIC(uint8_t, PIC, PIC, pic)
    ENUM_KEY_NUMERIC(uint8_t, fixed, 0u, PIC, PIC, pic, PIC)
    ENUM_KEY_NUMERIC(uint8_t, pic, 1u, PIC, PIC, pic, PIC)
    ENUM_KEY_NUMERIC(uint8_t, pie, 2u, PIC, PIC, pic, PIC)
END_ENUM_NUMERIC(uint8_t, PIC, PIC, pic)

BEGIN_ENUM_NUMERIC(uint32_t, CppStdRevision, CPPSTDREVISION, cppstdrevision)
    ENUM_KEY_NUMERIC(uint32_t, cpp98, 199711u, CppStdRevision, CPPSTDREVISION, cppstdrevision, CSR)
    ENUM_KEY_NUMERIC(uint32_t, cpp11, 201103u, CppStdRevision, CPPSTDREVISION, cppstdrevision, CSR)
    ENUM_KEY_NUMERIC(uint32_t, cpp14, 201402u, CppStdRevision, CPPSTDREVISION, cppstdrevision, CSR)
    ENUM_KEY_NUMERIC(uint32_t, cpp17, 201703u, CppStdRevision, CPPSTDREVISION, cppstdrevision, CSR)
END_ENUM_NUMERIC(uint32_t, CppStdRevision, CPPSTDREVISION, cppstdrevision)

BEGIN_ENUM_NUMERIC(uint32_t, CxxHeaderMode, CXXHEADERMODE, cxxheadermode)
    ENUM_KEY_NUMERIC(uint32_t, none, 0u, CxxHeaderMode, CXXHEADERMODE, cxxheadermode, CHM)
    ENUM_KEY_NUMERIC(uint32_t, silent, 1u, CxxHeaderMode, CXXHEADERMODE, cxxheadermode, CHM)
    ENUM_KEY_NUMERIC(uint32_t, verbose, 2u, CxxHeaderMode, CXXHEADERMODE, cxxheadermode, CHM)
END_ENUM_NUMERIC(uint32_t, CxxHeaderMode, CXXHEADERMODE, cxxheadermode)

struct Param
{
    bool obj;
    bool link;
    bool dll;
    bool lib;
    bool multiobj;
    bool oneobj;
    bool trace;
    bool tracegc;
    bool verbose;
    bool vcg_ast;
    bool showColumns;
    bool vtls;
    bool vtemplates;
    bool vtemplatesListInstances;
    bool vgc;
    bool vfield;
    bool vcomplex;
    uint8_t symdebug;
    bool symdebugref;
    bool alwaysframe;
    bool optimize;
    bool map;
    bool is64bit;
    bool isLP64;
    bool isLinux;
    bool isOSX;
    bool isWindows;
    bool isFreeBSD;
    bool isOpenBSD;
    bool isDragonFlyBSD;
    bool isSolaris;
    bool hasObjectiveC;
    bool mscoff;
    DiagnosticReporting useDeprecated;
    bool stackstomp;
    bool useUnitTests;
    bool useInline;
    bool useDIP25;
    bool noDIP25;
    bool useDIP1021;
    bool release;
    bool preservePaths;
    DiagnosticReporting warnings;
    PIC pic;
    bool color;
    bool cov;
    uint8_t covPercent;
    bool ctfe_cov;
    bool nofloat;
    bool ignoreUnsupportedPragmas;
    bool useModuleInfo;
    bool useTypeInfo;
    bool useExceptions;
    bool noSharedAccess;
    bool previewIn;
    bool betterC;
    bool addMain;
    bool allInst;
    bool fix16997;
    bool fixAliasThis;
    bool vsafe;
    bool ehnogc;
    bool dtorFields;
    bool fieldwise;
    bool rvalueRefParam;
    CppStdRevision cplusplus;
    bool markdown;
    bool vmarkdown;
    bool showGaggedErrors;
    bool printErrorContext;
    bool manual;
    bool usage;
    bool mcpuUsage;
    bool transitionUsage;
    bool checkUsage;
    bool checkActionUsage;
    bool revertUsage;
    bool previewUsage;
    bool externStdUsage;
    bool hcUsage;
    bool logo;
    CPU cpu;
    CHECKENABLE useInvariants;
    CHECKENABLE useIn;
    CHECKENABLE useOut;
    CHECKENABLE useArrayBounds;
    CHECKENABLE useAssert;
    CHECKENABLE useSwitchError;
    CHECKENABLE boundscheck;
    CHECKACTION checkAction;
    uint32_t errorLimit;
    DArray< const char > argv0;
    Array<const char*> modFileAliasStrings;
    Array<const char*>* imppath;
    Array<const char*>* fileImppath;
    DArray< const char > objdir;
    DArray< const char > objname;
    DArray< const char > libname;
    bool doDocComments;
    DArray< const char > docdir;
    DArray< const char > docname;
    Array<const char*> ddocfiles;
    bool doHdrGeneration;
    DArray< const char > hdrdir;
    DArray< const char > hdrname;
    bool hdrStripPlainFunctions;
    CxxHeaderMode doCxxHdrGeneration;
    DArray< const char > cxxhdrdir;
    DArray< const char > cxxhdrname;
    bool doJsonGeneration;
    DArray< const char > jsonfilename;
    JsonFieldFlags jsonFieldFlags;
    OutBuffer* mixinOut;
    const char* mixinFile;
    int32_t mixinLines;
    uint32_t debuglevel;
    Array<const char*>* debugids;
    uint32_t versionlevel;
    Array<const char*>* versionids;
    DArray< const char > defaultlibname;
    DArray< const char > debuglibname;
    DArray< const char > mscrtlib;
    DArray< const char > moduleDepsFile;
    OutBuffer* moduleDeps;
    MessageStyle messageStyle;
    bool debugb;
    bool debugc;
    bool debugf;
    bool debugr;
    bool debugx;
    bool debugy;
    bool run;
    Array<const char*> runargs;
    Array<const char*> objfiles;
    Array<const char*> linkswitches;
    Array<bool> linkswitchIsForCC;
    Array<const char*> libfiles;
    Array<const char*> dllfiles;
    DArray< const char > deffile;
    DArray< const char > resfile;
    DArray< const char > exefile;
    DArray< const char > mapfile;
    ~Param();
    Param() :
        obj(true),
        link(true),
        dll(),
        lib(),
        multiobj(),
        oneobj(),
        trace(),
        tracegc(),
        verbose(),
        vcg_ast(),
        showColumns(),
        vtls(),
        vtemplates(),
        vtemplatesListInstances(),
        vgc(),
        vfield(),
        vcomplex(),
        symdebug(),
        symdebugref(),
        alwaysframe(),
        optimize(),
        map(),
        is64bit(true),
        isLP64(),
        isLinux(),
        isOSX(),
        isWindows(),
        isFreeBSD(),
        isOpenBSD(),
        isDragonFlyBSD(),
        isSolaris(),
        hasObjectiveC(),
        mscoff(false),
        useDeprecated((DiagnosticReporting)1u),
        stackstomp(),
        useUnitTests(),
        useInline(false),
        useDIP25(),
        noDIP25(),
        useDIP1021(),
        release(),
        preservePaths(),
        warnings((DiagnosticReporting)2u),
        pic((PIC)0u),
        color(),
        cov(),
        covPercent(),
        ctfe_cov(false),
        nofloat(),
        ignoreUnsupportedPragmas(),
        useModuleInfo(true),
        useTypeInfo(true),
        useExceptions(true),
        noSharedAccess(),
        previewIn(),
        betterC(),
        addMain(),
        allInst(),
        fix16997(),
        fixAliasThis(),
        vsafe(),
        ehnogc(),
        dtorFields(),
        fieldwise(),
        rvalueRefParam(),
        cplusplus((CppStdRevision)199711u),
        markdown(true),
        vmarkdown(),
        showGaggedErrors(),
        printErrorContext(),
        manual(),
        usage(),
        mcpuUsage(),
        transitionUsage(),
        checkUsage(),
        checkActionUsage(),
        revertUsage(),
        previewUsage(),
        externStdUsage(),
        hcUsage(),
        logo(),
        cpu((CPU)11),
        useInvariants((CHECKENABLE)0u),
        useIn((CHECKENABLE)0u),
        useOut((CHECKENABLE)0u),
        useArrayBounds((CHECKENABLE)0u),
        useAssert((CHECKENABLE)0u),
        useSwitchError((CHECKENABLE)0u),
        boundscheck((CHECKENABLE)0u),
        checkAction((CHECKACTION)0u),
        errorLimit(20u),
        argv0(),
        modFileAliasStrings(),
        imppath(),
        fileImppath(),
        objdir(),
        objname(),
        libname(),
        doDocComments(),
        docdir(),
        docname(),
        ddocfiles(),
        doHdrGeneration(),
        hdrdir(),
        hdrname(),
        hdrStripPlainFunctions(true),
        cxxhdrdir(),
        cxxhdrname(),
        doJsonGeneration(),
        jsonfilename(),
        mixinOut(),
        mixinFile(),
        mixinLines(),
        debuglevel(),
        debugids(),
        versionlevel(),
        versionids(),
        defaultlibname(),
        debuglibname(),
        mscrtlib(),
        moduleDepsFile(),
        moduleDeps(),
        messageStyle((MessageStyle)0u),
        debugb(),
        debugc(),
        debugf(),
        debugr(),
        debugx(),
        debugy(),
        run(),
        runargs(),
        objfiles(),
        linkswitches(),
        linkswitchIsForCC(),
        libfiles(),
        dllfiles(),
        deffile(),
        resfile(),
        exefile(),
        mapfile()
    {
    }
};

typedef uint32_t structalign_t;

ENUM_CONSTANT_NUMERIC(uint32_t, STRUCTALIGN_DEFAULT, 4294967295u)

struct Global
{
    DArray< const char > inifilename;
    DArray< char > mars_ext;
    DArray< const char > obj_ext;
    DArray< const char > lib_ext;
    DArray< const char > dll_ext;
    DArray< char > doc_ext;
    DArray< char > ddoc_ext;
    DArray< char > hdr_ext;
    DArray< char > cxxhdr_ext;
    DArray< char > json_ext;
    DArray< char > map_ext;
    bool run_noext;
    DArray< char > copyright;
    DArray< char > written;
    Array<const char*>* path;
    Array<const char*>* filePath;
    DArray< const char > vendor;
    Param params;
    uint32_t errors;
    uint32_t warnings;
    uint32_t gag;
    uint32_t gaggedErrors;
    uint32_t gaggedWarnings;
    void* console;
    Array<Identifier*>* versionids;
    Array<Identifier*>* debugids;
    ENUM_CONSTANT_NUMERIC(int32_t, recursionLimit, 500)

    uint32_t startGagging();
    bool endGagging(uint32_t oldGagged);
    void increaseErrorCount();
    void _init();
    uint32_t versionNumber();
    const char* const versionChars();
    ~Global();
    Global() :
        inifilename(),
        mars_ext("d"),
        obj_ext(),
        lib_ext(),
        dll_ext(),
        doc_ext("html"),
        ddoc_ext("ddoc"),
        hdr_ext("di"),
        cxxhdr_ext("h"),
        json_ext("json"),
        map_ext("map"),
        run_noext(),
        copyright("Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved"),
        written("written by Walter Bright"),
        path(),
        filePath(),
        vendor(),
        params(),
        errors(),
        warnings(),
        gag(),
        gaggedErrors(),
        gaggedWarnings(),
        console(),
        versionids(),
        debugids()
    {
    }
};

typedef uint64_t dinteger_t;

typedef int64_t sinteger_t;

typedef uint64_t uinteger_t;

typedef int8_t d_int8;

typedef uint8_t d_uns8;

typedef int16_t d_int16;

typedef uint16_t d_uns16;

typedef int32_t d_int32;

typedef uint32_t d_uns32;

typedef int64_t d_int64;

typedef uint64_t d_uns64;

typedef uint64_t StorageClass;

extern Global global;

struct Id
{
    static Identifier* IUnknown;
    static Identifier* Object;
    static Identifier* object;
    static Identifier* string;
    static Identifier* wstring;
    static Identifier* dstring;
    static Identifier* max;
    static Identifier* min;
    static Identifier* This;
    static Identifier* _super;
    static Identifier* ctor;
    static Identifier* dtor;
    static Identifier* __xdtor;
    static Identifier* __fieldDtor;
    static Identifier* __aggrDtor;
    static Identifier* cppdtor;
    static Identifier* ticppdtor;
    static Identifier* postblit;
    static Identifier* __xpostblit;
    static Identifier* __fieldPostblit;
    static Identifier* __aggrPostblit;
    static Identifier* classInvariant;
    static Identifier* unitTest;
    static Identifier* require;
    static Identifier* ensure;
    static Identifier* capture;
    static Identifier* this2;
    static Identifier* _init;
    static Identifier* __sizeof;
    static Identifier* __xalignof;
    static Identifier* _mangleof;
    static Identifier* stringof;
    static Identifier* _tupleof;
    static Identifier* length;
    static Identifier* remove;
    static Identifier* ptr;
    static Identifier* array;
    static Identifier* funcptr;
    static Identifier* dollar;
    static Identifier* ctfe;
    static Identifier* offset;
    static Identifier* offsetof;
    static Identifier* ModuleInfo;
    static Identifier* ClassInfo;
    static Identifier* classinfo;
    static Identifier* typeinfo;
    static Identifier* outer;
    static Identifier* Exception;
    static Identifier* RTInfo;
    static Identifier* Throwable;
    static Identifier* Error;
    static Identifier* withSym;
    static Identifier* result;
    static Identifier* returnLabel;
    static Identifier* line;
    static Identifier* empty;
    static Identifier* p;
    static Identifier* q;
    static Identifier* __vptr;
    static Identifier* __monitor;
    static Identifier* gate;
    static Identifier* __c_long;
    static Identifier* __c_ulong;
    static Identifier* __c_longlong;
    static Identifier* __c_ulonglong;
    static Identifier* __c_long_double;
    static Identifier* __c_wchar_t;
    static Identifier* cpp_type_info_ptr;
    static Identifier* _assert;
    static Identifier* _unittest;
    static Identifier* _body;
    static Identifier* printf;
    static Identifier* scanf;
    static Identifier* TypeInfo;
    static Identifier* TypeInfo_Class;
    static Identifier* TypeInfo_Interface;
    static Identifier* TypeInfo_Struct;
    static Identifier* TypeInfo_Enum;
    static Identifier* TypeInfo_Pointer;
    static Identifier* TypeInfo_Vector;
    static Identifier* TypeInfo_Array;
    static Identifier* TypeInfo_StaticArray;
    static Identifier* TypeInfo_AssociativeArray;
    static Identifier* TypeInfo_Function;
    static Identifier* TypeInfo_Delegate;
    static Identifier* TypeInfo_Tuple;
    static Identifier* TypeInfo_Const;
    static Identifier* TypeInfo_Invariant;
    static Identifier* TypeInfo_Shared;
    static Identifier* TypeInfo_Wild;
    static Identifier* elements;
    static Identifier* _arguments_typeinfo;
    static Identifier* _arguments;
    static Identifier* _argptr;
    static Identifier* destroy;
    static Identifier* xopEquals;
    static Identifier* xopCmp;
    static Identifier* xtoHash;
    static Identifier* LINE;
    static Identifier* FILE;
    static Identifier* MODULE;
    static Identifier* FUNCTION;
    static Identifier* PRETTY_FUNCTION;
    static Identifier* DATE;
    static Identifier* TIME;
    static Identifier* TIMESTAMP;
    static Identifier* VENDOR;
    static Identifier* VERSIONX;
    static Identifier* EOFX;
    static Identifier* nan;
    static Identifier* infinity;
    static Identifier* dig;
    static Identifier* epsilon;
    static Identifier* mant_dig;
    static Identifier* max_10_exp;
    static Identifier* max_exp;
    static Identifier* min_10_exp;
    static Identifier* min_exp;
    static Identifier* min_normal;
    static Identifier* re;
    static Identifier* im;
    static Identifier* C;
    static Identifier* D;
    static Identifier* Windows;
    static Identifier* Pascal;
    static Identifier* System;
    static Identifier* Objective;
    static Identifier* exit;
    static Identifier* success;
    static Identifier* failure;
    static Identifier* keys;
    static Identifier* values;
    static Identifier* rehash;
    static Identifier* future;
    static Identifier* property;
    static Identifier* nogc;
    static Identifier* live;
    static Identifier* safe;
    static Identifier* trusted;
    static Identifier* system;
    static Identifier* disable;
    static Identifier* ___out;
    static Identifier* ___in;
    static Identifier* __int;
    static Identifier* _dollar;
    static Identifier* __LOCAL_SIZE;
    static Identifier* uadd;
    static Identifier* neg;
    static Identifier* com;
    static Identifier* add;
    static Identifier* add_r;
    static Identifier* sub;
    static Identifier* sub_r;
    static Identifier* mul;
    static Identifier* mul_r;
    static Identifier* div;
    static Identifier* div_r;
    static Identifier* mod;
    static Identifier* mod_r;
    static Identifier* eq;
    static Identifier* cmp;
    static Identifier* iand;
    static Identifier* iand_r;
    static Identifier* ior;
    static Identifier* ior_r;
    static Identifier* ixor;
    static Identifier* ixor_r;
    static Identifier* shl;
    static Identifier* shl_r;
    static Identifier* shr;
    static Identifier* shr_r;
    static Identifier* ushr;
    static Identifier* ushr_r;
    static Identifier* cat;
    static Identifier* cat_r;
    static Identifier* assign;
    static Identifier* addass;
    static Identifier* subass;
    static Identifier* mulass;
    static Identifier* divass;
    static Identifier* modass;
    static Identifier* andass;
    static Identifier* orass;
    static Identifier* xorass;
    static Identifier* shlass;
    static Identifier* shrass;
    static Identifier* ushrass;
    static Identifier* catass;
    static Identifier* postinc;
    static Identifier* postdec;
    static Identifier* index;
    static Identifier* indexass;
    static Identifier* slice;
    static Identifier* sliceass;
    static Identifier* call;
    static Identifier* _cast;
    static Identifier* opIn;
    static Identifier* opIn_r;
    static Identifier* opStar;
    static Identifier* opDot;
    static Identifier* opDispatch;
    static Identifier* opDollar;
    static Identifier* opUnary;
    static Identifier* opIndexUnary;
    static Identifier* opSliceUnary;
    static Identifier* opBinary;
    static Identifier* opBinaryRight;
    static Identifier* opOpAssign;
    static Identifier* opIndexOpAssign;
    static Identifier* opSliceOpAssign;
    static Identifier* pow;
    static Identifier* pow_r;
    static Identifier* powass;
    static Identifier* classNew;
    static Identifier* classDelete;
    static Identifier* apply;
    static Identifier* applyReverse;
    static Identifier* Fempty;
    static Identifier* Ffront;
    static Identifier* Fback;
    static Identifier* FpopFront;
    static Identifier* FpopBack;
    static Identifier* aaLen;
    static Identifier* aaKeys;
    static Identifier* aaValues;
    static Identifier* aaRehash;
    static Identifier* monitorenter;
    static Identifier* monitorexit;
    static Identifier* criticalenter;
    static Identifier* criticalexit;
    static Identifier* __ArrayPostblit;
    static Identifier* __ArrayDtor;
    static Identifier* _d_delThrowable;
    static Identifier* _d_assert_fail;
    static Identifier* dup;
    static Identifier* _aaApply;
    static Identifier* _aaApply2;
    static Identifier* Pinline;
    static Identifier* lib;
    static Identifier* linkerDirective;
    static Identifier* mangle;
    static Identifier* msg;
    static Identifier* startaddress;
    static Identifier* crt_constructor;
    static Identifier* crt_destructor;
    static Identifier* tohash;
    static Identifier* tostring;
    static Identifier* getmembers;
    static Identifier* __alloca;
    static Identifier* main;
    static Identifier* WinMain;
    static Identifier* DllMain;
    static Identifier* CMain;
    static Identifier* rt_init;
    static Identifier* __cmp;
    static Identifier* __equals;
    static Identifier* __switch;
    static Identifier* __switch_error;
    static Identifier* __ArrayCast;
    static Identifier* _d_HookTraceImpl;
    static Identifier* _d_arraysetlengthTImpl;
    static Identifier* _d_arraysetlengthT;
    static Identifier* _d_arraysetlengthTTrace;
    static Identifier* stdc;
    static Identifier* stdarg;
    static Identifier* va_start;
    static Identifier* std;
    static Identifier* core;
    static Identifier* etc;
    static Identifier* attribute;
    static Identifier* math;
    static Identifier* trig;
    static Identifier* sin;
    static Identifier* cos;
    static Identifier* tan;
    static Identifier* _sqrt;
    static Identifier* _pow;
    static Identifier* atan2;
    static Identifier* rint;
    static Identifier* ldexp;
    static Identifier* rndtol;
    static Identifier* exp;
    static Identifier* expm1;
    static Identifier* exp2;
    static Identifier* yl2x;
    static Identifier* yl2xp1;
    static Identifier* log;
    static Identifier* log2;
    static Identifier* log10;
    static Identifier* round;
    static Identifier* floor;
    static Identifier* trunc;
    static Identifier* fmax;
    static Identifier* fmin;
    static Identifier* fma;
    static Identifier* isnan;
    static Identifier* isInfinity;
    static Identifier* isfinite;
    static Identifier* ceil;
    static Identifier* copysign;
    static Identifier* fabs;
    static Identifier* toPrec;
    static Identifier* simd;
    static Identifier* __prefetch;
    static Identifier* __simd_sto;
    static Identifier* __simd;
    static Identifier* __simd_ib;
    static Identifier* bitop;
    static Identifier* bsf;
    static Identifier* bsr;
    static Identifier* btc;
    static Identifier* btr;
    static Identifier* bts;
    static Identifier* bswap;
    static Identifier* volatile;
    static Identifier* volatileLoad;
    static Identifier* volatileStore;
    static Identifier* _popcnt;
    static Identifier* inp;
    static Identifier* inpl;
    static Identifier* inpw;
    static Identifier* outp;
    static Identifier* outpl;
    static Identifier* outpw;
    static Identifier* isAbstractClass;
    static Identifier* isArithmetic;
    static Identifier* isAssociativeArray;
    static Identifier* isFinalClass;
    static Identifier* isTemplate;
    static Identifier* isPOD;
    static Identifier* isDeprecated;
    static Identifier* isDisabled;
    static Identifier* isFuture;
    static Identifier* isNested;
    static Identifier* isFloating;
    static Identifier* isIntegral;
    static Identifier* isScalar;
    static Identifier* isStaticArray;
    static Identifier* isUnsigned;
    static Identifier* isVirtualFunction;
    static Identifier* isVirtualMethod;
    static Identifier* isAbstractFunction;
    static Identifier* isFinalFunction;
    static Identifier* isOverrideFunction;
    static Identifier* isStaticFunction;
    static Identifier* isModule;
    static Identifier* isPackage;
    static Identifier* isRef;
    static Identifier* isOut;
    static Identifier* isLazy;
    static Identifier* hasMember;
    static Identifier* identifier;
    static Identifier* getProtection;
    static Identifier* parent;
    static Identifier* child;
    static Identifier* getMember;
    static Identifier* getOverloads;
    static Identifier* getVirtualFunctions;
    static Identifier* getVirtualMethods;
    static Identifier* classInstanceSize;
    static Identifier* allMembers;
    static Identifier* derivedMembers;
    static Identifier* isSame;
    static Identifier* compiles;
    static Identifier* parameters;
    static Identifier* getAliasThis;
    static Identifier* getAttributes;
    static Identifier* getFunctionAttributes;
    static Identifier* getFunctionVariadicStyle;
    static Identifier* getParameterStorageClasses;
    static Identifier* getLinkage;
    static Identifier* getUnitTests;
    static Identifier* getVirtualIndex;
    static Identifier* getPointerBitmap;
    static Identifier* isReturnOnStack;
    static Identifier* isZeroInit;
    static Identifier* getTargetInfo;
    static Identifier* getLocation;
    static Identifier* hasPostblit;
    static Identifier* hasCopyConstructor;
    static Identifier* isCopyable;
    static Identifier* allocator;
    static Identifier* basic_string;
    static Identifier* basic_istream;
    static Identifier* basic_ostream;
    static Identifier* basic_iostream;
    static Identifier* char_traits;
    static Identifier* udaGNUAbiTag;
    static Identifier* udaSelector;
    static Identifier* NULL;
    static Identifier* TRUE;
    static Identifier* FALSE;
    static Identifier* unsigned;
    static Identifier* wchar_t;
    static void initialize();
    Id()
    {
    }
};

class Identifier : public RootObject
{
public:
    int32_t value;
    bool isAnonymous_;
    DArray< char > name;
    static Identifier* create(const char* name);
    const char* toChars() const;
    int32_t getValue() const;
    bool isAnonymous() const;
    const char* toHChars2() const;
    DYNCAST dyncast() const;
    static Identifier* generateId(const char* prefix, size_t length, size_t suffix);
    static Identifier* idPool(const char* s, uint32_t len);
    static bool isValidIdentifier(const char* str);
};

struct Token
{
    Token* next;
    Loc loc;
    const char* ptr;
    TOK value;
    DArray< const char > blockComment;
    DArray< const char > lineComment;
    union
    {
        int64_t intvalue;
        uinteger_t unsvalue;
        _d_real floatvalue;
        struct
        {
            const char* ustring;
            uint32_t len;
            uint8_t postfix;
        };
        Identifier* ident;
    };
    int32_t isKeyword() const;
    void setString(const char* ptr, size_t length);
    void setString(const OutBuffer& buf);
    void setString();
    const char* toChars() const;
    static const char* toChars(uint8_t value);
    Token() :
        next(),
        loc(),
        ptr(),
        blockComment(),
        lineComment()
    {
    }
};

template <typename T>
struct Array
{
    // Ignoring var length alignment 0
    size_t length;
    // Ignoring var data alignment 0
    DArray< T > data;
    // Ignoring var SMALLARRAYCAP alignment 0
    // Ignoring var smallarray alignment 0
    void* smallarray;
    typedef length opDollar;
    typedef length dim;
};

struct CTFloat
{
    ENUM_CONSTANT_NUMERIC(bool, yl2x_supported, true)

    ENUM_CONSTANT_NUMERIC(bool, yl2xp1_supported, true)

    static void yl2x(const _d_real* const x, const _d_real* const y, _d_real* res);
    static void yl2xp1(const _d_real* const x, const _d_real* const y, _d_real* res);
    static _d_real sin(_d_real x);
    static _d_real cos(_d_real x);
    static _d_real tan(_d_real x);
    static _d_real sqrt(_d_real x);
    static _d_real fabs(_d_real x);
    static _d_real ldexp(_d_real n, int32_t exp);
    static _d_real round(_d_real x);
    static _d_real floor(_d_real x);
    static _d_real ceil(_d_real x);
    static _d_real trunc(_d_real x);
    static _d_real log(_d_real x);
    static _d_real log2(_d_real x);
    static _d_real log10(_d_real x);
    static _d_real pow(_d_real x, _d_real y);
    static _d_real exp(_d_real x);
    static _d_real expm1(_d_real x);
    static _d_real exp2(_d_real x);
    static _d_real copysign(_d_real x, _d_real s);
    static _d_real fmin(_d_real x, _d_real y);
    static _d_real fmax(_d_real x, _d_real y);
    static _d_real fma(_d_real x, _d_real y, _d_real z);
    static bool isIdentical(_d_real a, _d_real b);
    static size_t hash(_d_real a);
    static bool isNaN(_d_real r);
    static bool isSNaN(_d_real r);
    static bool isInfinity(_d_real r);
    static _d_real parse(const char* literal, bool* isOutOfRange);
    static int32_t sprint(char* str, char fmt, _d_real x);
    static _d_real zero;
    static _d_real one;
    static _d_real minusone;
    static _d_real half;
    static void initialize();
    CTFloat()
    {
    }
};

typedef Array<const char*> Strings;

struct Port
{
    static int32_t memicmp(const char* const s1, const char* const s2, size_t n);
    static char* strupr(char* s);
    static bool isFloat32LiteralOutOfRange(const char* s);
    static bool isFloat64LiteralOutOfRange(const char* s);
    static void writelongLE(uint32_t value, void* buffer);
    static uint32_t readlongLE(const void* const buffer);
    static void writelongBE(uint32_t value, void* buffer);
    static uint32_t readlongBE(const void* const buffer);
    static uint32_t readwordLE(const void* const buffer);
    static uint32_t readwordBE(const void* const buffer);
    static void valcpy(void* dst, uint64_t val, size_t size);
    Port()
    {
    }
};

ENUM_CONSTANT_NUMERIC(bool, isGCAvailable, true)

struct Mem
{
    static char* xstrdup(const char* s);
    static void xfree(void* p);
    static void* xmalloc(size_t size);
    static void* xmalloc_noscan(size_t size);
    static void* xcalloc(size_t size, size_t n);
    static void* xcalloc_noscan(size_t size, size_t n);
    static void* xrealloc(void* p, size_t size);
    static void* xrealloc_noscan(void* p, size_t size);
    static void* error();
    static void* check(void* p);
    static bool _isGCEnabled;
    static bool isGCEnabled();
    static void disableGC();
    static void addRange(const void* p, size_t size);
    static void removeRange(const void* p);
    Mem()
    {
    }
};

extern const Mem mem;

ENUM_CONSTANT_NUMERIC(int32_t, CHUNK_SIZE, 1048512)

ENUM_CONSTANT_NUMERIC(bool, OVERRIDE_MEMALLOC, true)

extern "C" void* _d_allocmemory(size_t m_size);

extern "C" Object* _d_newclass(const TypeInfo_Class* const ci);

extern "C" void* _d_newitemT(TypeInfo* ti);

extern "C" void* _d_newitemiT(TypeInfo* ti);

