// Automatically generated by Digital Mars D Compiler

#pragma once

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

#ifdef CUSTOM_D_ARRAY_TYPE
#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
#else
/// Represents a D [] array
template<typename T>
struct _d_dynamicArray
{
    size_t length;
    T *ptr;

    _d_dynamicArray() : length(0), ptr(NULL) { }

    _d_dynamicArray(size_t length_in, T *ptr_in)
        : length(length_in), ptr(ptr_in) { }

    T& operator[](const size_t idx) {
        assert(idx < length);
        return ptr[idx];
    }

    const T& operator[](const size_t idx) const {
        assert(idx < length);
        return ptr[idx];
    }
};
#endif
#if !defined(_d_real)
# define _d_real long double
#endif

class RootObject;
enum class DYNCAST
{
    object = 0,
    expression = 1,
    dsymbol = 2,
    type = 3,
    identifier = 4,
    tuple = 5,
    parameter = 6,
    statement = 7,
    condition = 8,
    templateparameter = 9,
};

class Visitor;
class Identifier;
class Dsymbol;
class CPPNamespaceDeclaration;
struct Symbol;
struct Loc;
struct Global;
struct Scope;
enum class PASS
{
    init = 0,
    semantic = 1,
    semanticdone = 2,
    semantic2 = 3,
    semantic2done = 4,
    semantic3 = 5,
    semantic3done = 6,
    inline = 7,
    inlinedone = 8,
    obj = 9,
};

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 AliasAssign;
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;
enum class Kind : uint8_t
{
    undefined = 0u,
    none = 1u,
    private_ = 2u,
    package_ = 3u,
    protected_ = 4u,
    public_ = 5u,
    export_ = 6u,
};

struct BitArray;
enum class CPPMANGLE : uint8_t
{
    def = 0u,
    asStruct = 1u,
    asClass = 2u,
};

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;
enum class LINK : uint8_t
{
    default_ = 0u,
    d = 1u,
    c = 2u,
    cpp = 3u,
    windows = 4u,
    objc = 5u,
    system = 6u,
};

class LinkDeclaration;
enum class PINLINE : uint8_t
{
    default_ = 0u,
    never = 1u,
    always = 2u,
};

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

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

class StringExp;
class TupleExp;
enum class MATCH
{
    nomatch = 0,
    convert = 1,
    constant = 2,
    exact = 3,
};

enum class Modifiable
{
    no = 0,
    yes = 1,
    initialization = 2,
};

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 MixinExp;
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;
struct ObjcFuncDeclaration;
struct ObjcSelector;
enum class PURE : uint8_t
{
    impure = 0u,
    fwdref = 1u,
    weak = 2u,
    const_ = 3u,
    strong = 4u,
};

struct ParameterList;
enum class VarArg : uint8_t
{
    none = 0u,
    variadic = 1u,
    typesafe = 2u,
};

enum class JsonFieldFlags : uint32_t
{
    none = 0u,
    compilerInfo = 1u,
    buildInfo = 2u,
    modules = 4u,
    semantics = 8u,
};

struct ObNode;
class StoppableVisitor;
struct Token;
struct code;
struct TargetC;
struct TargetCPP;
struct TargetObjC;
struct Param;
struct Target;
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;
private:
    virtual void __vtable_slot_0();
public:
    virtual DYNCAST dyncast() const;
};

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

extern Global global;

struct Loc
{
    const char* filename;
    uint32_t linnum;
    uint32_t charnum;
    const char* toChars(bool showColumns = global.params.showColumns, uint8_t messageStyle = static_cast<uint8_t>(global.params.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;
    const char* comment;
    const Loc loc;
    Scope* _scope;
    const 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* toParentP(Dsymbol* p1, Dsymbol* p2 = nullptr);
    TemplateInstance* isInstantiated();
    bool followInstantiationContext(Dsymbol* p1, Dsymbol* p2 = nullptr);
    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 AliasAssign* isAliasAssign();
    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 : uint64_t { ChunkSize = 8LLU };

    enum : uint64_t { BitsPerChunk = 64LLU };

private:
    size_t len;
    uint64_t* ptr;
public:
    BitArray()
    {
    }
};

class ScopeDsymbol : public Dsymbol
{
public:
    Array<Dsymbol* >* members;
    DsymbolTable* symtab;
    uint32_t endlinnum;
private:
    Array<Dsymbol* >* importedScopes;
    Kind* prots;
    BitArray accessiblePackages;
    BitArray privateAccessiblePackages;
public:
    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:
    const 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);
    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();
    MixinExp* isMixinExp();
    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;
    _d_dynamicArray< FuncDeclaration* > methodList;
    bool isRootClass() const;
    ObjcClassDeclaration() :
        isMeta(false),
        isExtern(false),
        identifier(),
        classDeclaration(),
        metaclass(),
        methodList()
    {
    }
};

struct FileName
{
private:
    _d_dynamicArray< const char > str;
public:
    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 = nullptr);
    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 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()
        {
        }
    };

private:
    Mcache* mcache;
public:
    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 = nullptr);
    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(AliasAssign* 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(MixinExp* 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;
    bool isOptional;
    ObjcFuncDeclaration() :
        selector(),
        selectorParameter(),
        isOptional()
    {
    }
};

struct ParameterList
{
    Array<Parameter* >* parameters;
    StorageClass stc;
    VarArg varargs;
    ParameterList(Array<Parameter* >* parameters, VarArg varargs = (VarArg)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* thunkMangle(FuncDeclaration* fd, int32_t offset);
    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()
    {
    }
};

enum class Sizeok : uint8_t
{
    none = 0u,
    fwd = 1u,
    inProcess = 2u,
    done = 3u,
};

enum class Baseok : uint8_t
{
    none = 0u,
    start = 1u,
    done = 2u,
    semanticdone = 3u,
};

enum class ClassKind : uint8_t
{
    d = 0u,
    cpp = 1u,
    objc = 2u,
};

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 final : 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 = nullptr);

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 final : public StorageClassDeclaration
{
public:
    Expression* msg;
    const char* msgstr;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    void setScope(Scope* sc);
    void accept(Visitor* v);
};

class LinkDeclaration final : 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 final : 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 final : 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 final : 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 final : public AttribDeclaration
{
public:
    Expression* ealign;
    enum : uint32_t { UNKNOWN = 0u };

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

class AnonDeclaration final : 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 final : public AttribDeclaration
{
public:
    Array<Expression* >* args;
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    PINLINE evalPragmaInline(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 final : public ConditionalDeclaration
{
public:
    ScopeDsymbol* scopesym;
private:
    bool addisdone;
    bool onStack;
public:
    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 final : 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 final : 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 final : 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 final : 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);
};

enum class BE
{
    none = 0,
    fallthru = 1,
    throw_ = 2,
    return_ = 4,
    goto_ = 8,
    halt = 16,
    break_ = 32,
    continue_ = 64,
    errthrow = 128,
    any = 31,
};

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);

enum class TargetOS : uint8_t
{
    linux = 1u,
    Windows = 2u,
    OSX = 4u,
    OpenBSD = 8u,
    FreeBSD = 16u,
    Solaris = 32u,
    DragonFlyBSD = 64u,
    all = 119u,
    Posix = 117u,
};

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;
    complex_t() = delete;
    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);

enum class Include : uint8_t
{
    notComputed = 0u,
    yes = 1u,
    no = 2u,
};

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 final : public RootObject
{
public:
    Loc loc;
    ForeachStatement* aggrfe;
    ForeachRangeStatement* rangefe;
    bool needExpansion;
    StaticForeach* syntaxCopy();
};

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

class DebugCondition final : 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 final : 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 final : public Condition
{
public:
    Expression* exp;
    Condition* syntaxCopy();
    int32_t include(Scope* sc);
    void accept(Visitor* v);
    const char* toChars() const;
};

enum class CppOperator
{
    Cast = 0,
    Assign = 1,
    Eq = 2,
    Index = 3,
    Call = 4,
    Unary = 5,
    Binary = 6,
    OpAssign = 7,
    Unknown = 8,
};

extern const char* toCppMangleItanium(Dsymbol* s);

extern const char* cppTypeInfoMangleItanium(Dsymbol* s);

extern const char* cppThunkMangleItanium(FuncDeclaration* fd, int32_t offset);

extern const char* toCppMangleMSVC(Dsymbol* s);

extern const char* cppTypeInfoMangleMSVC(Dsymbol* s);

class ClassReferenceExp final : public Expression
{
public:
    StructLiteralExp* value;
    ClassDeclaration* originalClass();
    int32_t findFieldIndexByName(VarDeclaration* v);
    void accept(Visitor* v);
};

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

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

enum class CSX : uint16_t
{
    none = 0u,
    this_ctor = 1u,
    super_ctor = 2u,
    label = 4u,
    return_ = 8u,
    any_ctor = 16u,
    halt = 32u,
};

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

enum class Abstract : uint8_t
{
    fwdref = 0u,
    yes = 1u,
    no = 2u,
};

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

enum class ClassFlags : uint32_t
{
    none = 0u,
    isCOMclass = 1u,
    noPointers = 2u,
    hasOffTi = 4u,
    hasCtor = 8u,
    hasGetMembers = 16u,
    hasTypeInfo = 32u,
    isAbstract = 64u,
    isCPPclass = 128u,
    hasDtor = 256u,
};

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;
    _d_dynamicArray< BaseClass* > interfaces;
    Array<BaseClass* >* vtblInterfaces;
    TypeInfoClassDeclaration* vclassinfo;
    bool com;
    bool stack;
    int32_t cppDtorVtblIndex;
private:
    bool inuse;
public:
    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);
    const char* toPrettyChars(bool qualifyTypes = false);
    Dsymbol* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    bool isBaseOf2(ClassDeclaration* cd);
    enum : int32_t { OFFSET_RUNTIME = 1985229328 };

    enum : 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 final : 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);

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

class Declaration : public Dsymbol
{
public:
    Type* type;
    Type* originalType;
    StorageClass storage_class;
    Prot protection;
    LINK linkage;
    int16_t inuse;
    uint8_t adFlags;
    enum : int32_t { wasRead = 1 };

    enum : int32_t { ignoreRead = 2 };

    _d_dynamicArray< const 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 final : 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 final : 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 final : 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;
    Array<FuncDeclaration* > nestedrefs;
    Dsymbol* aliassym;
    VarDeclaration* lastVar;
    Expression* edtor;
    IntRange* range;
    Array<VarDeclaration* >* maybes;
    uint32_t endlinnum;
    uint32_t offset;
    uint32_t sequenceNumber;
    static uint32_t nextSequenceNumber;
    uint32_t alignment;
    enum : uint32_t { AdrOnStackNone = 4294967295u };

    uint32_t ctfeAdrOnStack;
    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;
    static VarDeclaration* create(const Loc& loc, Type* type, Identifier* ident, Initializer* _init, StorageClass storage_class = static_cast<StorageClass>(STC::undefined_));
    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 final : 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 final : public TypeInfoDeclaration
{
public:
    static TypeInfoStructDeclaration* create(Type* tinfo);
    void accept(Visitor* v);
    ~TypeInfoStructDeclaration();
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class EnumDeclaration final : 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 final : 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 final : 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
{
private:
    Macro* mactab;
public:
    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);

enum class PKG
{
    unknown = 0,
    module_ = 1,
    package_ = 2,
};

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 final : 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;
    _d_dynamicArray< const char > arg;
    ModuleDeclaration* md;
    const FileName srcfile;
    const FileName objfile;
    const FileName hdrfile;
    FileName docfile;
    FileBuffer* srcBuffer;
    uint32_t errors;
    uint32_t numlines;
    bool isHdrFile;
    bool isDocFile;
    bool hasAlwaysInlines;
    bool isPackageFile;
    Package* pkg;
    Array<const 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);

enum class SCOPE
{
    ctor = 1,
    noaccesscheck = 2,
    condition = 4,
    debug_ = 8,
    constraint = 16,
    invariant_ = 32,
    require = 64,
    ensure = 96,
    contract = 96,
    ctfe = 128,
    compile = 256,
    ignoresymbolvisibility = 512,
    onlysafeaccess = 1024,
    free = 32768,
    fullinst = 65536,
    alias_ = 131072,
    printf = 262144,
    scanf = 524288,
};

extern FuncDeclaration* search_toString(StructDeclaration* sd);

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

enum class StructFlags
{
    none = 0,
    hasPointers = 1,
};

enum class StructPOD
{
    no = 0,
    yes = 1,
    fwd = 2,
};

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 final : public StructDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    const char* kind() const;
    UnionDeclaration* isUnionDeclaration();
    void accept(Visitor* v);
    ~UnionDeclaration();
};

enum
{
    IgnoreNone = 0,
    IgnorePrivateImports = 1,
    IgnoreErrors = 2,
    IgnoreAmbiguous = 4,
    SearchLocalsOnly = 8,
    SearchImportsOnly = 16,
    SearchUnqualifiedModule = 32,
    IgnoreSymbolVisibility = 128,
};

class WithScopeSymbol final : 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 final : public ScopeDsymbol
{
    RootObject* arrayContent;
public:
    Scope* sc;
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 0);
    ArrayScopeSymbol* isArrayScopeSymbol();
    void accept(Visitor* v);
    ~ArrayScopeSymbol();
};

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

class ForwardingScopeDsymbol final : 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 final : public Dsymbol
{
public:
    Expression* exp;
    ExpressionDsymbol(Expression* exp);
    ExpressionDsymbol* isExpressionDsymbol();
};

class AliasAssign final : public Dsymbol
{
public:
    Identifier* ident;
    Type* type;
    Dsymbol* syntaxCopy(Dsymbol* s);
    AliasAssign* isAliasAssign();
    const char* kind() const;
    void accept(Visitor* v);
};

class DsymbolTable final : 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();
};

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

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 final : public RootObject
{
public:
    Array<RootObject* > objects;
    DYNCAST dyncast() const;
    const char* toChars() const;
    ~Tuple();
};

class TemplateDeclaration final : 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;
private:
    Expression* lastConstraint;
    Array<Expression* > lastConstraintNegs;
    Array<RootObject* >* lastConstraintTiargs;
public:
    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);
    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 final : 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 final : public TemplateTypeParameter
{
public:
    TemplateThisParameter* isTemplateThisParameter();
    TemplateParameter* syntaxCopy();
    void accept(Visitor* v);
};

class TemplateValueParameter final : 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 final : 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 final : 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;
private:
    uint16_t _nest;
public:
    uint8_t inuse;
private:
    enum class Flag : uint32_t
    {
        semantictiargsdone = 32768u,
        havetempdecl = 16384u,
        gagged = 8192u,
        available = 8191u,
    };

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

class TemplateMixin final : 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();
};

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

class ToCppBuffer final : public Visitor
{
public:
    enum class EnumKind
    {
        Int = 0,
        Numeric = 1,
        String = 2,
        Enum = 3,
        Other = 4,
    };

    typedef ASTCodegen AST;
    void* visited;
    void* forwarded;
    OutBuffer* fwdbuf;
    OutBuffer* checkbuf;
    OutBuffer* donebuf;
    OutBuffer* buf;
    AggregateDeclaration* adparent;
    TemplateDeclaration* tdparent;
    Identifier* ident;
    LINK linkage;
    bool forwardedAA;
    Type** origType;
    Kind currentProt;
    STC storageClass;
    int32_t ignoredCounter;
    bool hasReal;
    const bool printIgnored;
    ToCppBuffer(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf);
    void writeDeclEnd();
    void visit(Dsymbol* s);
    void visit(Import* i);
    void visit(AttribDeclaration* pd);
    void visit(StorageClassDeclaration* scd);
    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);
    void visit(StructDeclaration* sd);
    void visit(ClassDeclaration* cd);
    void visit(EnumDeclaration* ed);
    void visit(EnumMember* em);
    void visit(Type* t);
    void visit(TypeIdentifier* t);
    void visit(TypeNull* t);
    void visit(TypeTypeof* t);
    void visit(TypeBasic* t);
    void visit(TypePointer* t);
    void visit(TypeSArray* t);
    void visit(TypeAArray* t);
    void visit(TypeFunction* tf);
    void visit(TypeEnum* t);
    void visit(TypeStruct* t);
    void visit(TypeDArray* t);
    void visit(TypeInstance* t);
    void visit(TemplateDeclaration* td);
    void visit(TypeClass* t);
    void visit(Parameter* p);
    void visit(Expression* e);
    void visit(VarExp* e);
    void visit(CallExp* e);
    void visit(DotVarExp* e);
    void visit(DotIdExp* e);
    void visit(NullExp* e);
    void visit(ArrayLiteralExp* e);
    void visit(StringExp* e);
    void visit(RealExp* e);
    void visit(IntegerExp* e);
    void visit(StructLiteralExp* sle);
};

class DebugSymbol final : 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 final : 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);
};

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

struct UnionExp
{
    Expression* exp();
    Expression* copy();
    #pragma pack(push, 8)
private:
    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];
    };
    #pragma pack(pop)

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

enum class OwnedBy : uint8_t
{
    code = 0u,
    ctfe = 1u,
    cache = 2u,
};

class IntegerExp final : public Expression
{
    dinteger_t value;
public:
    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 final : public Expression
{
public:
    static ErrorExp* get();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
    static ErrorExp* errorexp;
};

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

class RealExp final : 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 final : 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 final : public IdentifierExp
{
public:
    void accept(Visitor* v);
};

class DsymbolExp final : 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 final : public ThisExp
{
public:
    void accept(Visitor* v);
};

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

class StringExp final : public Expression
{
    union
    {
        char* string;
        char16_t* wstring;
        char32_t* dstring;
    };
public:
    size_t len;
    uint8_t sz;
    uint8_t committed;
    enum : 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 final : 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 final : 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 final : 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);
};

class StructLiteralExp final : 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 = nullptr);
    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 final : public Expression
{
public:
    Expression* syntaxCopy();
    bool checkType();
    bool checkValue();
    void accept(Visitor* v);
};

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

class TemplateExp final : 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 final : 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 final : 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 final : public SymbolExp
{
public:
    dinteger_t offset;
    bool isBool(bool result);
    void accept(Visitor* v);
};

class VarExp final : 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 final : public Expression
{
public:
    OverloadSet* vars;
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class FuncExp final : 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 final : public Expression
{
public:
    Dsymbol* declaration;
    Expression* syntaxCopy();
    bool hasCode();
    void accept(Visitor* v);
};

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

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

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

class IsExp final : 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 MixinExp final : public Expression
{
public:
    Array<Expression* >* exps;
    Expression* syntaxCopy();
    bool equals(const RootObject* const o) const;
    void accept(Visitor* v);
};

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

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

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

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

class DotVarExp final : 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 final : public UnaExp
{
public:
    TemplateInstance* ti;
    Expression* syntaxCopy();
    bool findTempDecl(Scope* sc);
    void accept(Visitor* v);
};

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

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

class CallExp final : 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 final : public UnaExp
{
public:
    void accept(Visitor* v);
};

class PtrExp final : 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 final : public UnaExp
{
public:
    void accept(Visitor* v);
};

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

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

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

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

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

class VectorExp final : 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 final : public UnaExp
{
public:
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

class SliceExp final : 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 final : public UnaExp
{
public:
    void accept(Visitor* v);
};

class ArrayExp final : 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 final : public BinExp
{
public:
    void accept(Visitor* v);
};

class CommaExp final : public BinExp
{
public:
    const 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 final : public Expression
{
public:
    Expression* lwr;
    Expression* upr;
    Expression* syntaxCopy();
    void accept(Visitor* v);
};

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

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

class IndexExp final : 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 final : public BinExp
{
public:
    void accept(Visitor* v);
};

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

enum class MemorySet
{
    none = 0,
    blockAssign = 1,
    referenceInit = 2,
};

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 final : public AssignExp
{
public:
    void accept(Visitor* v);
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class CondExp final : 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 final : public DefaultInitExp
{
public:
    Expression* resolveLoc(const Loc& loc, Scope* sc);
    void accept(Visitor* v);
};

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

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

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

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

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

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

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

enum class ILS
{
    uninitialized = 0,
    no = 1,
    yes = 2,
};

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

enum class FUNCFLAG : uint32_t
{
    purityInprocess = 1u,
    safetyInprocess = 2u,
    nothrowInprocess = 4u,
    nogcInprocess = 8u,
    returnInprocess = 16u,
    inlineScanned = 32u,
    inferScope = 64u,
    hasCatches = 128u,
    compileTimeOnly = 256u,
    printf = 512u,
    scanf = 1024u,
};

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;
    const 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 : 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();
    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();
};

enum class FuncResolveFlag : uint8_t
{
    standard = 0u,
    quiet = 1u,
    overloadOnly = 2u,
};

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

class FuncLiteralDeclaration final : 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 final : 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 final : 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 final : 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 final : 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 final : public StaticDtorDeclaration
{
public:
    Dsymbol* syntaxCopy(Dsymbol* s);
    SharedStaticDtorDeclaration* isSharedStaticDtorDeclaration();
    void accept(Visitor* v);
    ~SharedStaticDtorDeclaration();
};

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

class UnitTestDeclaration final : 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 final : 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();
};

extern void genhdrfile(Module* m);

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

extern const char* parametersTypeToChars(ParameterList pl);

enum class NeedInterpret
{
    INITnointerpret = 0,
    INITinterpret = 1,
};

enum class InitKind : uint8_t
{
    void_ = 0u,
    error = 1u,
    struct_ = 2u,
    array = 3u,
    exp = 4u,
};

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 final : public Initializer
{
public:
    Type* type;
    void accept(Visitor* v);
};

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

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

class ArrayInitializer final : 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 final : 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 = nullptr);

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

extern JsonFieldFlags tryParseJsonField(const char* fieldName);

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

typedef uint8_t TY;

enum class MODFlags
{
    const_ = 1,
    immutable_ = 4,
    shared_ = 2,
    wild = 8,
    wildconst = 9,
    mutable = 16,
};

typedef uint8_t MOD;

enum class DotExpFlag
{
    gag = 1,
    noDeref = 2,
};

class TypeError final : 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 final : public Type
{
public:
    const 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 final : 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 final : 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 final : 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 final : 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 final : 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 final : 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);
};

enum class RET
{
    regs = 1,
    stack = 2,
};

enum class TRUST : uint8_t
{
    default_ = 0u,
    system = 1u,
    trusted = 2u,
    safe = 3u,
};

enum class TRUSTformat
{
    TRUSTformatDefault = 0,
    TRUSTformatSystem = 1,
};

class TypeFunction final : public TypeNext
{
public:
    ParameterList parameterList;
private:
    enum class FunctionFlag : uint32_t
    {
        none = 0u,
        isnothrow = 1u,
        isnogc = 2u,
        isproperty = 4u,
        isref = 8u,
        isreturn = 16u,
        isscope = 32u,
        isreturninferred = 64u,
        isscopeinferred = 128u,
        islive = 256u,
        incomplete = 512u,
        inoutParam = 1024u,
        inoutQual = 2048u,
    };

public:
    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);
    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;
    bool attributesEqual(const TypeFunction* const other) const;
    void accept(Visitor* v);
};

class TypeDelegate final : 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 final : 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 final : 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 final : public TypeQualified
{
public:
    Identifier* ident;
    Dsymbol* originalSymbol;
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    void accept(Visitor* v);
    ~TypeIdentifier();
};

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

class TypeTypeof final : 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 final : public TypeQualified
{
public:
    const char* kind() const;
    Type* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    void accept(Visitor* v);
    ~TypeReturn();
};

enum class AliasThisRec
{
    no = 0,
    yes = 1,
    fwdref = 2,
    typeMask = 3,
    tracing = 4,
    tracingDT = 8,
};

class TypeStruct final : 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 final : public Type
{
public:
    EnumDeclaration* sym;
    const char* kind() const;
    Type* syntaxCopy();
    d_uns64 size(const Loc& loc);
    Type* memType(const Loc& loc = Loc::initial);
    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 final : 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 final : 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 final : public TypeNext
{
public:
    Expression* lwr;
    Expression* upr;
    const char* kind() const;
    Type* syntaxCopy();
    void accept(Visitor* v);
};

class TypeNull final : 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 final : 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 = global.params.previewIn) const;
private:
    enum class SR
    {
        None = 0,
        Scope = 1,
        ReturnScope = 2,
        Ref = 3,
        ReturnRef = 4,
        RefScope = 5,
        ReturnRef_Scope = 6,
        Ref_ReturnScope = 7,
    };

};

extern AggregateDeclaration* isAggregate(Type* t);

class NOGCVisitor final : 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 final : 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;

enum class ObType : uint8_t
{
    goto_ = 0u,
    return_ = 1u,
    retexp = 2u,
    throw_ = 3u,
    exit = 4u,
    try_ = 5u,
    finally_ = 6u,
    fend = 7u,
};

enum class PtrState : uint8_t
{
    Initial = 0u,
    Undefined = 1u,
    Owner = 2u,
    Borrowed = 3u,
    Readonly = 4u,
};

class Objc
{
public:
    static void _init();
    static void deinitialize();
    virtual void setObjc(ClassDeclaration* cd) = 0;
    virtual void setObjc(InterfaceDeclaration* ) = 0;
    virtual const char* toPrettyChars(ClassDeclaration* classDeclaration, bool qualifyTypes) 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 void setAsOptional(FuncDeclaration* functionDeclaration, Scope* sc) const = 0;
    virtual void validateOptional(FuncDeclaration* functionDeclaration) 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;
};

enum class ParseStatementFlags
{
    semi = 1,
    scope_ = 2,
    curly = 4,
    curlyScope = 8,
    semiOk = 16,
};

enum class PREC
{
    zero = 0,
    expr = 1,
    assign = 2,
    cond = 3,
    oror = 4,
    andand = 5,
    or = 6,
    xor = 7,
    and = 8,
    equal = 9,
    rel = 10,
    shift = 11,
    add = 12,
    mul = 13,
    pow = 14,
    unary = 15,
    primary = 16,
};

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

template <typename AST>
class PermissiveVisitor : public ParseTimeVisitor<AST >
{
public:
    typedef ParseTimeVisitor<AST > visit;
    virtual void visit(typename AST::Dsymbol );
    virtual void visit(typename AST::Parameter );
    virtual void visit(typename AST::Statement );
    virtual void visit(typename AST::Type );
    virtual void visit(typename AST::Expression );
    virtual void visit(typename AST::TemplateParameter );
    virtual void visit(typename AST::Condition );
    virtual void visit(typename AST::Initializer );
};

class PostorderStatementVisitor final : 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);
};

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

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

extern bool isTrivialExp(Expression* e);

extern bool hasSideEffect(Expression* e);

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

class Statement : public ASTNode
{
public:
    const Loc loc;
    const 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 final : public Statement
{
public:
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class PeelStatement final : 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 final : public ExpStatement
{
public:
    VarDeclaration* var;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class CompileStatement final : public Statement
{
public:
    Array<Expression* >* exps;
    Statement* syntaxCopy();
    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 final : public CompoundStatement
{
public:
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class UnrolledLoopStatement final : 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 final : public Statement
{
public:
    ForwardingScopeDsymbol* sym;
    Statement* statement;
    Statement* syntaxCopy();
    Array<Statement* >* flatten(Scope* sc);
    void accept(Visitor* v);
};

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

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

class ForStatement final : 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 final : 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 final : 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 final : public Statement
{
public:
    Parameter* prm;
    Expression* condition;
    Statement* ifbody;
    Statement* elsebody;
    VarDeclaration* match;
    Loc endloc;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

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

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

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

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

class SwitchStatement final : 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 final : public Statement
{
public:
    Expression* exp;
    Statement* statement;
    int32_t index;
    VarDeclaration* lastVar;
    void* extra;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

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

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

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

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

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

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

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

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

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

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

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

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

class TryFinallyStatement final : 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 final : 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 final : public Statement
{
public:
    Expression* exp;
    bool internalThrow;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

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

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

class LabelStatement final : 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 final : 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 final : public AsmStatement
{
public:
    code* asmcode;
    uint32_t asmalign;
    uint32_t regs;
    bool refparam;
    bool naked;
    Statement* syntaxCopy();
    void accept(Visitor* v);
};

class GccAsmStatement final : 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 final : public CompoundStatement
{
public:
    StorageClass stc;
    CompoundAsmStatement* syntaxCopy();
    Array<Statement* >* flatten(Scope* sc);
    void accept(Visitor* v);
};

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

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

class StaticAssert final : 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;
    _d_dynamicArray< 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()
        {
        }
    };

    FPTypeProperties<float > FloatProperties;
    FPTypeProperties<double > DoubleProperties;
    FPTypeProperties<_d_real > RealProperties;
private:
    Type* tvalist;
    const Param* params;
public:
    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 = nullptr);
    LINK systemLinkage();
    TypeTuple* toArgTypes(Type* t);
    bool isReturnOnStack(TypeFunction* tf, bool needsThis);
    uint64_t parameterSize(const Loc& loc, Type* t);
    bool preferPassByRef(Type* t);
private:
    enum class TargetInfoKeys
    {
        cppRuntimeLibrary = 0,
        cppStd = 1,
        floatAbi = 2,
        objectFormat = 3,
    };

public:
    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);

template <typename AST>
class ParseTimeTransitiveVisitor : public PermissiveVisitor<AST >
{
public:
    typedef PermissiveVisitor<AST > visit;
};

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);

enum class Color
{
    black = 0,
    red = 1,
    green = 2,
    blue = 4,
    yellow = 3,
    magenta = 5,
    cyan = 6,
    lightGray = 7,
    bright = 8,
    darkGray = 8,
    brightRed = 9,
    brightGreen = 10,
    brightBlue = 12,
    brightYellow = 11,
    brightMagenta = 13,
    brightCyan = 14,
    white = 15,
};

namespace Classification
{
    static Color const error = (Color)9;
    static Color const gagged = (Color)12;
    static Color const warning = (Color)11;
    static Color const deprecation = (Color)14;
    static Color const tip = (Color)10;
};

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 = nullptr, const char* p2 = nullptr, 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 = nullptr, const char* p2 = nullptr);

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();

enum class HIGHLIGHT : uint8_t
{
    Default = 0u,
    Escape = 255u,
    Identifier = 15u,
    Keyword = 15u,
    Literal = 15u,
    Comment = 8u,
    Other = 6u,
};

enum class TargetOS : uint8_t
{
    linux = 1u,
    Windows = 2u,
    OSX = 4u,
    OpenBSD = 8u,
    FreeBSD = 16u,
    Solaris = 32u,
    DragonFlyBSD = 64u,
    all = 119u,
    Posix = 117u,
};

enum class TARGET : bool
{
    Linux = true,
    OSX = false,
    FreeBSD = false,
    OpenBSD = false,
    Solaris = false,
    Windows = false,
    DragonFlyBSD = false,
};

enum class DiagnosticReporting : uint8_t
{
    error = 0u,
    inform = 1u,
    off = 2u,
};

enum class MessageStyle : uint8_t
{
    digitalmars = 0u,
    gnu = 1u,
};

enum class CHECKENABLE : uint8_t
{
    _default = 0u,
    off = 1u,
    on = 2u,
    safeonly = 3u,
};

enum class CHECKACTION : uint8_t
{
    D = 0u,
    C = 1u,
    halt = 2u,
    context = 3u,
};

enum class CPU
{
    x87 = 0,
    mmx = 1,
    sse = 2,
    sse2 = 3,
    sse3 = 4,
    ssse3 = 5,
    sse4_1 = 6,
    sse4_2 = 7,
    avx = 8,
    avx2 = 9,
    avx512 = 10,
    baseline = 11,
    native = 12,
};

enum class PIC : uint8_t
{
    fixed = 0u,
    pic = 1u,
    pie = 2u,
};

enum class CppStdRevision : uint32_t
{
    cpp98 = 199711u,
    cpp11 = 201103u,
    cpp14 = 201402u,
    cpp17 = 201703u,
    cpp20 = 202002u,
};

enum class CxxHeaderMode : uint32_t
{
    none = 0u,
    silent = 1u,
    verbose = 2u,
};

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;
    TargetOS targetOS;
    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 inclusiveInContracts;
    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;
    _d_dynamicArray< const char > argv0;
    Array<const char* > modFileAliasStrings;
    Array<const char* >* imppath;
    Array<const char* >* fileImppath;
    _d_dynamicArray< const char > objdir;
    _d_dynamicArray< const char > objname;
    _d_dynamicArray< const char > libname;
    bool doDocComments;
    _d_dynamicArray< const char > docdir;
    _d_dynamicArray< const char > docname;
    Array<const char* > ddocfiles;
    bool doHdrGeneration;
    _d_dynamicArray< const char > hdrdir;
    _d_dynamicArray< const char > hdrname;
    bool hdrStripPlainFunctions;
    CxxHeaderMode doCxxHdrGeneration;
    _d_dynamicArray< const char > cxxhdrdir;
    _d_dynamicArray< const char > cxxhdrname;
    bool doJsonGeneration;
    _d_dynamicArray< 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;
    _d_dynamicArray< const char > defaultlibname;
    _d_dynamicArray< const char > debuglibname;
    _d_dynamicArray< const char > mscrtlib;
    _d_dynamicArray< const char > moduleDepsFile;
    OutBuffer* moduleDeps;
    _d_dynamicArray< const char > makeDepsFile;
    OutBuffer* makeDeps;
    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;
    _d_dynamicArray< const char > deffile;
    _d_dynamicArray< const char > resfile;
    _d_dynamicArray< const char > exefile;
    _d_dynamicArray< 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(),
        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(),
        inclusiveInContracts(),
        vsafe(),
        ehnogc(),
        dtorFields(),
        fieldwise(),
        rvalueRefParam(),
        cplusplus((CppStdRevision)201103u),
        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(),
        makeDepsFile(),
        makeDeps(),
        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;

struct Global
{
    _d_dynamicArray< const char > inifilename;
    _d_dynamicArray< const char > mars_ext;
    _d_dynamicArray< const char > obj_ext;
    _d_dynamicArray< const char > lib_ext;
    _d_dynamicArray< const char > dll_ext;
    _d_dynamicArray< const char > doc_ext;
    _d_dynamicArray< const char > ddoc_ext;
    _d_dynamicArray< const char > hdr_ext;
    _d_dynamicArray< const char > cxxhdr_ext;
    _d_dynamicArray< const char > json_ext;
    _d_dynamicArray< const char > map_ext;
    bool run_noext;
    _d_dynamicArray< const char > copyright;
    _d_dynamicArray< const char > written;
    Array<const char* >* path;
    Array<const char* >* filePath;
    _d_dynamicArray< 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 : 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(1, "d"),
        obj_ext(),
        lib_ext(),
        dll_ext(),
        doc_ext(4, "html"),
        ddoc_ext(4, "ddoc"),
        hdr_ext(2, "di"),
        cxxhdr_ext(1, "h"),
        json_ext(4, "json"),
        map_ext(3, "map"),
        run_noext(),
        copyright(73, "Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved"),
        written(24, "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;

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* 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* getCppNamespaces;
    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* udaOptional;
    static Identifier* NULL;
    static Identifier* TRUE;
    static Identifier* FALSE;
    static Identifier* unsigned;
    static Identifier* wchar_t;
    static void initialize();
    Id()
    {
    }
};

class Identifier final : public RootObject
{
    const int32_t value;
    const bool isAnonymous_;
    const _d_dynamicArray< const char > name;
public:
    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;
    _d_dynamicArray< const char > blockComment;
    _d_dynamicArray< 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
    _d_dynamicArray< T > data;
    // Ignoring var SMALLARRAYCAP alignment 0
    // Ignoring var smallarray alignment 0
    void* smallarray;
    Array(size_t dim);
    ~Array();
    const char* toChars() const;
    Array& push(T ptr);
    Array& append(Array* a);
    void reserve(size_t nentries);
    void remove(size_t i);
    void insert(size_t index, Array* a);
    void insert(size_t index, T ptr);
    void setDim(size_t newdim);
    size_t find(T ptr) const;
    bool contains(T ptr) const;
    T& opIndex(size_t i);
    T* tdata();
    Array<T >* copy() const;
    void shift(T ptr);
    void zero();
    T pop();
    typedef length opDollar;
    typedef length dim;
    Array()
    {
    }
};

struct CTFloat
{
    enum : bool { yl2x_supported = true };

    enum : 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 = nullptr);
    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()
    {
    }
};

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;

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);

