// Automatically generated by Digital Mars D Compiler

#pragma once

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

#ifdef CUSTOM_D_ARRAY_TYPE
#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
#else
/// Represents a D [] array
template<typename T>
struct _d_dynamicArray final
{
    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 Visitor;
class Identifier;
struct Symbol;
struct Scope;
struct DsymbolAttributes;
class DeprecatedDeclaration;
class CPPNamespaceDeclaration;
class UserAttributeDeclaration;
class Module;
class TemplateInstance;
class AggregateDeclaration;
class LabelDsymbol;
class ClassDeclaration;
class Type;
class Package;
template <typename T>
struct Array;
class UnitTestDeclaration;
class EnumMember;
class TemplateDeclaration;
class TemplateMixin;
class ForwardingAttribDeclaration;
class Nspace;
class Declaration;
class StorageClassDeclaration;
class ExpressionDsymbol;
class AliasAssign;
class ThisDeclaration;
class BitFieldDeclaration;
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 ScopeDsymbol;
class ForwardingScopeDsymbol;
class WithScopeSymbol;
class ArrayScopeSymbol;
class Import;
class EnumDeclaration;
class SymbolDeclaration;
class AttribDeclaration;
class AnonDeclaration;
class VisibilityDeclaration;
class OverloadSet;
class MixinDeclaration;
class StaticAssert;
class StaticIfDeclaration;
class CAsmDeclaration;
class DsymbolTable;
struct MangleOverride;
class AliasThis;
class Expression;
class Condition;
class StaticForeach;
struct UnionExp;
class DebugCondition;
class VersionCondition;
class StaticIfCondition;
class ForeachStatement;
class ForeachRangeStatement;
struct OutBuffer;
class TypeInfoClassDeclaration;
class TypeTuple;
class Initializer;
struct IntRange;
struct ModuleDeclaration;
template <typename Datum>
struct FileMapping;
struct Escape;
class LabelStatement;
class SwitchStatement;
class Statement;
class TryFinallyStatement;
class ScopeGuardStatement;
class ErrorSink;
struct DocComment;
class WithStatement;
struct AA;
class CaseStatement;
class Catch;
struct Designator;
class GotoCaseStatement;
class GotoStatement;
class Parameter;
class ReturnStatement;
class ScopeStatement;
class TemplateParameter;
class TemplateTypeParameter;
class TemplateValueParameter;
class TemplateAliasParameter;
class TemplateThisParameter;
class TemplateTupleParameter;
struct TemplatePrevious;
class TypeQualified;
class TypeBasic;
class TypeFunction;
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 TypeNoreturn;
class TypeTag;
class StringExp;
class IntegerExp;
class ErrorExp;
class VoidInitExp;
class RealExp;
class ComplexExp;
class IdentifierExp;
class DollarExp;
class DsymbolExp;
class ThisExp;
class SuperExp;
class NullExp;
class InterpExp;
class TupleExp;
class ArrayLiteralExp;
class AssocArrayLiteralExp;
class StructLiteralExp;
class CompoundLiteralExp;
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 ThrowExp;
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 LoweredAssignExp;
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 GenericExp;
class DefaultInitExp;
class FileInitExp;
class LineInitExp;
class ModuleInitExp;
class FuncInitExp;
class PrettyFuncInitExp;
class ObjcClassReferenceExp;
class ClassReferenceExp;
class ThrownExceptionExp;
class UnaExp;
class BinExp;
class BinAssignExp;
struct InterpolatedSet;
struct ContractInfo;
struct ObjcSelector;
class ErrorInitializer;
class VoidInitializer;
class DefaultInitializer;
class StructInitializer;
class ArrayInitializer;
class ExpInitializer;
class CInitializer;
class ErrorStatement;
class PeelStatement;
class ExpStatement;
class CompoundStatement;
class IfStatement;
class ConditionalStatement;
class StaticForeachStatement;
class DefaultStatement;
class GotoDefaultStatement;
class BreakStatement;
class DtorExpStatement;
class MixinStatement;
class ForwardingStatement;
class DoStatement;
class WhileStatement;
class ForStatement;
class ContinueStatement;
class TryCatchStatement;
class ThrowStatement;
class DebugStatement;
class SwitchErrorStatement;
class UnrolledLoopStatement;
class CompoundDeclarationStatement;
class CompoundAsmStatement;
class PragmaStatement;
class StaticAssertStatement;
class CaseRangeStatement;
class SynchronizedStatement;
class AsmStatement;
class InlineAsmStatement;
class GccAsmStatement;
class ImportStatement;
struct Token;
struct Param;
class FileManager;
class Object;
class TypeInfo_Class;
class TypeInfo;

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

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

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

struct Loc final
{
private:
    uint32_t _linnum;
    uint32_t _charnum;
    uint32_t fileIndex;
public:
    static bool showColumns;
    static MessageStyle messageStyle;
    static void set(bool showColumns, MessageStyle messageStyle);
    Loc(const char* filename, uint32_t linnum, uint32_t charnum);
    uint32_t charnum() const;
    uint32_t charnum(uint32_t num);
    uint32_t linnum() const;
    uint32_t linnum(uint32_t num);
    const char* filename() const;
    void filename(const char* name);
    const char* toChars(bool showColumns = Loc::showColumns, MessageStyle messageStyle = Loc::messageStyle) const;
    bool equals(const Loc& loc) const;
    Loc() :
        _linnum(),
        _charnum(),
        fileIndex()
    {
    }
};

enum class PASS : uint8_t
{
    initial = 0u,
    semantic = 1u,
    semanticdone = 2u,
    semantic2 = 3u,
    semantic2done = 4u,
    semantic3 = 5u,
    semantic3done = 6u,
    inline_ = 7u,
    inlinedone = 8u,
    obj = 9u,
};

struct Ungag final
{
    uint32_t oldgag;
    ~Ungag();
    Ungag() :
        oldgag()
    {
    }
};

typedef uint64_t uinteger_t;

struct Visibility final
{
    enum class Kind : uint8_t
    {
        undefined = 0u,
        none = 1u,
        private_ = 2u,
        package_ = 3u,
        protected_ = 4u,
        public_ = 5u,
        export_ = 6u,
    };

    Kind kind;
    Package* pkg;
    Visibility(Kind kind, Package* pkg = nullptr);
    Visibility() :
        pkg()
    {
    }
};

class Dsymbol : public ASTNode
{
public:
    Identifier* ident;
    Dsymbol* parent;
    Symbol* csym;
    const Loc loc;
    Scope* _scope;
    const char* prettystring;
private:
    DsymbolAttributes* atts;
public:
    bool errors;
    PASS semanticRun;
    uint16_t localNum;
    static Dsymbol* create(Identifier* ident);
    const char* toChars() const override;
    DeprecatedDeclaration* depdecl();
    CPPNamespaceDeclaration* cppnamespace();
    UserAttributeDeclaration* userAttribDecl();
    DeprecatedDeclaration* depdecl(DeprecatedDeclaration* dd);
    CPPNamespaceDeclaration* cppnamespace(CPPNamespaceDeclaration* ns);
    UserAttributeDeclaration* userAttribDecl(UserAttributeDeclaration* uad);
    virtual const char* toPrettyCharsHelper();
    const Loc getLoc();
    const char* locToChars();
    bool equals(const RootObject* const o) const override;
    bool isAnonymous() const;
    Module* getModule();
    bool isCsymbol();
    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 final override;
    virtual Identifier* getIdent();
    virtual const char* toPrettyChars(bool QualifyTypes = false);
    virtual const char* kind() const;
    virtual Dsymbol* toAlias();
    virtual Dsymbol* toAlias2();
    virtual bool overloadInsert(Dsymbol* s);
    virtual uinteger_t 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 Visibility visible();
    virtual Dsymbol* syntaxCopy(Dsymbol* s);
    virtual bool oneMember(Dsymbol*& ps, Identifier* ident);
    virtual bool hasPointers();
    virtual bool hasStaticCtorOrDtor();
    virtual void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories);
    virtual void checkCtorConstInit();
    virtual void addComment(const char* comment);
    const char* comment();
    void comment(const char* comment);
    UnitTestDeclaration* ddocUnittest();
    void ddocUnittest(UnitTestDeclaration* utd);
    bool inNonRoot();
    static void deinitialize();
    void accept(Visitor* v) override;
    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 BitFieldDeclaration* isBitFieldDeclaration();
    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 VisibilityDeclaration* isVisibilityDeclaration();
    virtual OverloadSet* isOverloadSet();
    virtual MixinDeclaration* isMixinDeclaration();
    virtual StaticAssert* isStaticAssert();
    virtual StaticIfDeclaration* isStaticIfDeclaration();
    virtual CAsmDeclaration* isCAsmDeclaration();
};

struct BitArray final
{
    typedef uint64_t Chunk_t;
    enum : uint64_t { ChunkSize = 8LLU };

    enum : uint64_t { BitsPerChunk = 64LLU };

private:
    ~BitArray();
    size_t len;
    uint64_t* ptr;
public:
    BitArray() :
        len(),
        ptr()
    {
    }
    BitArray(uint64_t len, uint64_t* ptr = nullptr) :
        len(len),
        ptr(ptr)
        {}
};

class ScopeDsymbol : public Dsymbol
{
public:
    Array<Dsymbol* >* members;
    DsymbolTable* symtab;
    uint32_t endlinnum;
    Array<Dsymbol* >* importedScopes;
    Visibility::Kind* visibilities;
private:
    BitArray accessiblePackages;
    BitArray privateAccessiblePackages;
public:
    ScopeDsymbol* syntaxCopy(Dsymbol* s) override;
    virtual void importScope(Dsymbol* s, Visibility visibility);
    virtual bool isPackageAccessible(Package* p, Visibility visibility, uint32_t flags = 0u);
    bool isforwardRef() final override;
    static void multiplyDefined(const Loc& loc, Dsymbol* s1, Dsymbol* s2);
    const char* kind() const override;
    virtual Dsymbol* symtabInsert(Dsymbol* s);
    virtual Dsymbol* symtabLookup(Dsymbol* s, Identifier* id);
    bool hasStaticCtorOrDtor() override;
    ScopeDsymbol* isScopeDsymbol() final override;
    void accept(Visitor* v) override;
};

typedef uint64_t StorageClass;

template <typename T>
struct Array final
{
    size_t length;
    _d_dynamicArray< T > data;
    enum : int32_t { SMALLARRAYCAP = 1 };

    T smallarray[SMALLARRAYCAP];
    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 insert(size_t index, size_t count, T value);
    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();
    Array()
    {
    }
};

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

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

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

enum class LINK : uint8_t
{
    default_ = 0u,
    d = 1u,
    c = 2u,
    cpp = 3u,
    windows = 4u,
    objc = 5u,
    system = 6u,
};

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,
};

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

struct FileName final
{
private:
    _d_dynamicArray< const char > str;
public:
    static FileName create(const char* name);
    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(const 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() :
        str()
    {
    }
};

enum class ThreeState : uint8_t
{
    none = 0u,
    no = 1u,
    yes = 2u,
};

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

struct ObjcClassDeclaration final
{
    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()
    {
    }
};

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

enum class FileType : uint8_t
{
    d = 0u,
    dhdr = 1u,
    ddoc = 2u,
    c = 3u,
};

struct OutBuffer final
{
private:
    _d_dynamicArray< uint8_t > data;
    size_t offset;
    bool notlinehead;
    FileMapping<uint8_t >* fileMapping;
public:
    bool doindent;
    bool spaces;
    int32_t level;
    void dtor();
    ~OutBuffer();
    size_t length() const;
    char* extractData();
    void destroy();
    void reserve(size_t nbytes);
    void setsize(size_t size);
    void reset();
    void write(const void* data, size_t nbytes);
    void writestring(const char* s);
    void prependstring(const char* string);
    void writenl();
    void writeByten(int32_t b);
    void writeByte(uint32_t b);
    void writeUTF8(uint32_t b);
    void prependbyte(uint32_t b);
    void writewchar(uint32_t w);
    void writeword(uint32_t w);
    void writeUTF16(uint32_t w);
    void write4(uint32_t w);
    void write(const OutBuffer* const buf);
    void fill0(size_t nbytes);
    void vprintf(const char* format, va_list args);
    void printf(const char* format, ...);
    void print(uint64_t u);
    void bracket(char left, char right);
    size_t bracket(size_t i, const char* left, size_t j, const char* right);
    void spread(size_t offset, size_t nbytes);
    size_t insert(size_t offset, const void* p, size_t nbytes);
    void remove(size_t offset, size_t nbytes);
    char* peekChars();
    char* extractChars();
    OutBuffer() :
        data(),
        offset(),
        notlinehead(),
        fileMapping(),
        doindent(),
        spaces(),
        level()
    {
    }
};

struct MacroTable final
{
    typedef bool(*fp_t)(const char* p);
private:
    void* mactab;
public:
    MacroTable()
    {
    }
    MacroTable(void* mactab) :
        mactab(mactab)
        {}
};

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

struct FieldInit final
{
    CSX csx;
    Loc loc;
    FieldInit() :
        loc()
    {
    }
    FieldInit(CSX csx, Loc loc = Loc()) :
        csx(csx),
        loc(loc)
        {}
};

struct CtorFlow final
{
    CSX callSuper;
    _d_dynamicArray< FieldInit > fieldinit;
    CtorFlow() :
        fieldinit()
    {
    }
    CtorFlow(CSX callSuper, _d_dynamicArray< FieldInit > fieldinit = {}) :
        callSuper(callSuper),
        fieldinit(fieldinit)
        {}
};

template <typename K, typename V>
struct AssocArray final
{
    AA* aa;
    AssocArray()
    {
    }
};

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::CAsmDeclaration 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::MixinDeclaration 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::VisibilityDeclaration 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::BitFieldDeclaration 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::MixinStatement 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::TypeNoreturn 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::TypeTag 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::InterpExp 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::GenericExp 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::ThrowExp 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::CatElemAssignExp e);
    virtual void visit(typename AST::CatDcharAssignExp 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);
    virtual void visit(typename AST::DefaultInitializer i);
    virtual void visit(typename AST::CInitializer i);
};

struct MangleOverride final
{
    Dsymbol* agg;
    Identifier* id;
    MangleOverride() :
        agg(),
        id()
    {
    }
    MangleOverride(Dsymbol* agg, Identifier* id = nullptr) :
        agg(agg),
        id(id)
        {}
};

typedef Array<AliasDeclaration* > AliasDeclarations;

typedef Array<BaseClass* > BaseClasses;

typedef Array<CaseStatement* > CaseStatements;

typedef Array<Catch* > Catches;

typedef Array<ClassDeclaration* > ClassDeclarations;

struct DesigInit final
{
    Array<Designator >* designatorList;
    Initializer* initializer;
    DesigInit() :
        designatorList(),
        initializer()
    {
    }
    DesigInit(Array<Designator >* designatorList, Initializer* initializer = nullptr) :
        designatorList(designatorList),
        initializer(initializer)
        {}
};

typedef Array<DesigInit > DesigInits;

struct Designator final
{
    Expression* exp;
    Identifier* ident;
    Designator() :
        exp(),
        ident()
    {
    }
};

typedef Array<Designator > Designators;

typedef Array<Dsymbol* > Dsymbols;

typedef Array<DtorDeclaration* > DtorDeclarations;

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

typedef Array<Ensure > Ensures;

typedef Array<Expression* > Expressions;

typedef Array<FuncDeclaration* > FuncDeclarations;

typedef Array<GotoCaseStatement* > GotoCaseStatements;

typedef Array<GotoStatement* > GotoStatements;

typedef Array<Identifier* > Identifiers;

typedef Array<Initializer* > Initializers;

typedef Array<Module* > Modules;

typedef Array<RootObject* > Objects;

typedef Array<Parameter* > Parameters;

typedef Array<ReturnStatement* > ReturnStatements;

typedef Array<ScopeStatement* > ScopeStatements;

typedef Array<SharedStaticDtorDeclaration* > SharedStaticDtorDeclarations;

typedef Array<Statement* > Statements;

typedef Array<StaticDtorDeclaration* > StaticDtorDeclarations;

typedef Array<const char* > Strings;

typedef Array<TemplateInstance* > TemplateInstances;

typedef Array<TemplateParameter* > TemplateParameters;

typedef Array<Type* > Types;

typedef Array<VarDeclaration* > VarDeclarations;

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,
    hasNameSig = 512u,
};

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

struct MatchAccumulator final
{
    int32_t count;
    MATCH last;
    FuncDeclaration* lastf;
    FuncDeclaration* nextf;
    MatchAccumulator() :
        count(),
        last((MATCH)0),
        lastf(),
        nextf()
    {
    }
    MatchAccumulator(int32_t count, MATCH last = (MATCH)0, FuncDeclaration* lastf = nullptr, FuncDeclaration* nextf = nullptr) :
        count(count),
        last(last),
        lastf(lastf),
        nextf(nextf)
        {}
};

enum : char { PathSeparator = '/' };

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

struct FieldState final
{
    uint32_t offset;
    uint32_t fieldOffset;
    uint32_t fieldSize;
    uint32_t fieldAlign;
    uint32_t bitOffset;
    bool inFlight;
    FieldState() :
        offset(),
        fieldOffset(),
        fieldSize(),
        fieldAlign(),
        bitOffset(),
        inFlight()
    {
    }
    FieldState(uint32_t offset, uint32_t fieldOffset = 0u, uint32_t fieldSize = 0u, uint32_t fieldAlign = 0u, uint32_t bitOffset = 0u, bool inFlight = false) :
        offset(offset),
        fieldOffset(fieldOffset),
        fieldSize(fieldSize),
        fieldAlign(fieldAlign),
        bitOffset(bitOffset),
        inFlight(inFlight)
        {}
};

enum class SearchOpt : uint32_t
{
    all = 0u,
    ignorePrivateImports = 1u,
    ignoreErrors = 2u,
    ignoreAmbiguous = 4u,
    localsOnly = 8u,
    importsOnly = 16u,
    unqualifiedModule = 32u,
    tagNameSpace = 64u,
    ignoreVisibility = 128u,
};

typedef uint32_t SearchOptFlags;

enum : int32_t { IDX_NOTFOUND = 305419896 };

struct MATCHpair final
{
    MATCH mta;
    MATCH mfa;
    MATCHpair()
    {
    }
    MATCHpair(MATCH mta, MATCH mfa = (MATCH)0) :
        mta(mta),
        mfa(mfa)
        {}
};

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(const Loc& instLoc, Scope* sc) = 0;
    virtual bool hasDefaultArg() = 0;
    const char* toChars() const override;
    DYNCAST dyncast() const override;
    virtual RootObject* dummyArg() = 0;
    void accept(Visitor* v) override;
};

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

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_;
    Visibility visibility;
    TemplatePrevious* previous;
    Expression* lastConstraint;
    Array<Expression* > lastConstraintNegs;
    Array<RootObject* >* lastConstraintTiargs;
    TemplateDeclaration* syntaxCopy(Dsymbol* __param_0_) override;
    bool overloadInsert(Dsymbol* s) override;
    bool hasStaticCtorOrDtor() override;
    const char* kind() const override;
    const char* toChars() const override;
    Visibility visible() override;
    const char* getConstraintEvalError(const char*& tip);
    TemplateDeclaration* isTemplateDeclaration() override;
    bool isDeprecated() const override;
    bool isOverloadable() const override;
    void accept(Visitor* v) override;
};

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<Identifier* >* fnames;
    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:
    TemplateInstance* syntaxCopy(Dsymbol* s) override;
    Dsymbol* toAlias() final override;
    const char* kind() const override;
    bool oneMember(Dsymbol*& ps, Identifier* ident) override;
    const char* toChars() const override;
    const char* toPrettyCharsHelper() final override;
    Identifier* getIdent() final override;
    bool equalsx(TemplateInstance* ti);
    bool isDiscardable();
    bool needsCodegen();
    TemplateInstance* isTemplateInstance() final override;
    void accept(Visitor* v) override;
};

struct TemplateInstanceBox final
{
    TemplateInstance* ti;
    TemplateInstanceBox() :
        ti()
    {
    }
};

class TemplateMixin final : public TemplateInstance
{
public:
    TypeQualified* tqual;
    TemplateInstance* syntaxCopy(Dsymbol* s) override;
    const char* kind() const override;
    bool oneMember(Dsymbol*& ps, Identifier* ident) override;
    bool hasPointers() override;
    const char* toChars() const override;
    TemplateMixin* isTemplateMixin() override;
    void accept(Visitor* v) override;
};

struct TemplatePrevious final
{
    TemplatePrevious* prev;
    Scope* sc;
    Array<RootObject* >* dedargs;
    TemplatePrevious() :
        prev(),
        sc(),
        dedargs()
    {
    }
    TemplatePrevious(TemplatePrevious* prev, Scope* sc = nullptr, Array<RootObject* >* dedargs = nullptr) :
        prev(prev),
        sc(sc),
        dedargs(dedargs)
        {}
};

struct TemplateStats final
{
    uint32_t numInstantiations;
    uint32_t uniqueInstantiations;
    Array<TemplateInstance* >* allInstances;
    TemplateStats() :
        numInstantiations(),
        uniqueInstantiations(),
        allInstances()
    {
    }
    TemplateStats(uint32_t numInstantiations, uint32_t uniqueInstantiations = 0u, Array<TemplateInstance* >* allInstances = nullptr) :
        numInstantiations(numInstantiations),
        uniqueInstantiations(uniqueInstantiations),
        allInstances(allInstances)
        {}
};

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

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

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

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

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

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

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

    Mcache* mcache;
    Type* pto;
    Type* rto;
    Type* arrayof;
    TypeInfoDeclaration* vtinfo;
    void* 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* tnoreturn;
    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[48LLU];
    virtual const char* kind() const;
    Type* copy() const;
    virtual Type* syntaxCopy();
    bool equals(const RootObject* const o) const override;
    DYNCAST dyncast() const final override;
    size_t getUniqueID() const;
    const char* toChars() const final override;
    char* toPrettyChars(bool QualifyTypes = false);
    static void _init();
    static void deinitialize();
    uinteger_t size();
    virtual uinteger_t size(const Loc& loc);
    virtual uint32_t alignsize();
    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();
    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;
    bool hasDeprecatedAliasThis();
    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();
    Type* toBasetype();
    virtual MATCH implicitConvTo(Type* to);
    virtual MATCH constConv(Type* to);
    virtual uint8_t deduceWild(Type* t, bool isRef);
    virtual ClassDeclaration* isClassHandle();
    virtual structalign_t alignment();
    virtual Expression* defaultInitLiteral(const Loc& loc);
    virtual bool isZeroInit(const Loc& loc);
    virtual int32_t hasWild() const;
    virtual bool hasVoidInitPointers();
    virtual bool hasSystemFields();
    virtual bool hasInvariant();
    virtual Type* nextOf();
    Type* baseElemOf();
    uint32_t numberOfElems(const Loc& loc);
    virtual bool needsDestruction();
    virtual bool needsCopyOrPostblit();
    virtual bool needsNested();
    virtual TypeBasic* isTypeBasic();
    TypeFunction* isPtrToFunction();
    TypeFunction* isFunction_Delegate_PtrToFunction();
    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();
    TypeNoreturn* isTypeNoreturn();
    TypeTag* isTypeTag();
    void accept(Visitor* v) override;
    TypeFunction* toTypeFunction();
};

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

class DebugSymbol final : public Dsymbol
{
public:
    uint32_t level;
    DebugSymbol* syntaxCopy(Dsymbol* s) override;
    const char* toChars() const override;
    const char* kind() const override;
    DebugSymbol* isDebugSymbol() override;
    void accept(Visitor* v) override;
};

class VersionSymbol final : public Dsymbol
{
public:
    uint32_t level;
    VersionSymbol* syntaxCopy(Dsymbol* s) override;
    const char* toChars() const override;
    const char* kind() const override;
    VersionSymbol* isVersionSymbol() override;
    void accept(Visitor* v) override;
};

enum class EXP : uint8_t
{
    reserved = 0u,
    negate = 1u,
    cast_ = 2u,
    null_ = 3u,
    assert_ = 4u,
    array = 5u,
    call = 6u,
    address = 7u,
    type = 8u,
    throw_ = 9u,
    new_ = 10u,
    delete_ = 11u,
    star = 12u,
    symbolOffset = 13u,
    variable = 14u,
    dotVariable = 15u,
    dotIdentifier = 16u,
    dotTemplateInstance = 17u,
    dotType = 18u,
    slice = 19u,
    arrayLength = 20u,
    dollar = 21u,
    template_ = 22u,
    dotTemplateDeclaration = 23u,
    declaration = 24u,
    dSymbol = 25u,
    typeid_ = 26u,
    uadd = 27u,
    remove = 28u,
    newAnonymousClass = 29u,
    arrayLiteral = 30u,
    assocArrayLiteral = 31u,
    structLiteral = 32u,
    classReference = 33u,
    thrownException = 34u,
    delegatePointer = 35u,
    delegateFunctionPointer = 36u,
    lessThan = 37u,
    greaterThan = 38u,
    lessOrEqual = 39u,
    greaterOrEqual = 40u,
    equal = 41u,
    notEqual = 42u,
    identity = 43u,
    notIdentity = 44u,
    index = 45u,
    is_ = 46u,
    leftShift = 47u,
    rightShift = 48u,
    leftShiftAssign = 49u,
    rightShiftAssign = 50u,
    unsignedRightShift = 51u,
    unsignedRightShiftAssign = 52u,
    concatenate = 53u,
    concatenateAssign = 54u,
    concatenateElemAssign = 55u,
    concatenateDcharAssign = 56u,
    add = 57u,
    min = 58u,
    addAssign = 59u,
    minAssign = 60u,
    mul = 61u,
    div = 62u,
    mod = 63u,
    mulAssign = 64u,
    divAssign = 65u,
    modAssign = 66u,
    and_ = 67u,
    or_ = 68u,
    xor_ = 69u,
    andAssign = 70u,
    orAssign = 71u,
    xorAssign = 72u,
    assign = 73u,
    not_ = 74u,
    tilde = 75u,
    plusPlus = 76u,
    minusMinus = 77u,
    construct = 78u,
    blit = 79u,
    dot = 80u,
    comma = 81u,
    question = 82u,
    andAnd = 83u,
    orOr = 84u,
    prePlusPlus = 85u,
    preMinusMinus = 86u,
    identifier = 87u,
    string_ = 88u,
    interpolated = 89u,
    this_ = 90u,
    super_ = 91u,
    halt = 92u,
    tuple = 93u,
    error = 94u,
    void_ = 95u,
    int64 = 96u,
    float64 = 97u,
    complex80 = 98u,
    import_ = 99u,
    delegate_ = 100u,
    function_ = 101u,
    mixin_ = 102u,
    in_ = 103u,
    break_ = 104u,
    continue_ = 105u,
    goto_ = 106u,
    scope_ = 107u,
    traits = 108u,
    overloadSet = 109u,
    line = 110u,
    file = 111u,
    fileFullPath = 112u,
    moduleString = 113u,
    functionString = 114u,
    prettyFunction = 115u,
    pow = 116u,
    powAssign = 117u,
    vector = 118u,
    voidExpression = 119u,
    cantExpression = 120u,
    showCtfeContext = 121u,
    objcClassReference = 122u,
    vectorArray = 123u,
    compoundLiteral = 124u,
    _Generic_ = 125u,
    interval = 126u,
    loweredAssignExp = 127u,
};

typedef uint64_t dinteger_t;

struct complex_t final
{
    _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;
};

template <typename T>
struct Optional final
{
    T value;
    bool present;
    Optional(T value);
    static Optional<T > create(T val);
    bool isPresent() const;
    bool isEmpty() const;
    T get();
    bool hasValue(T exp) const;
    Optional()
    {
    }
};

class Expression : public ASTNode
{
public:
    Type* type;
    Loc loc;
    const EXP op;
    bool parens;
    size_t size() const;
    static void _init();
    static void deinitialize();
    virtual Expression* syntaxCopy();
    DYNCAST dyncast() const final override;
    const char* toChars() const override;
    virtual dinteger_t toInteger();
    virtual uinteger_t toUInteger();
    virtual _d_real toReal();
    virtual _d_real toImaginary();
    virtual complex_t toComplex();
    virtual StringExp* toStringExp();
    virtual bool isLvalue();
    virtual bool checkType();
    virtual bool checkValue();
    Expression* addressOf();
    Expression* deref();
    int32_t isConst();
    virtual bool isIdentical(const Expression* const e) const;
    virtual Optional<bool > toBool();
    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();
    InterpExp* isInterpExp();
    TupleExp* isTupleExp();
    ArrayLiteralExp* isArrayLiteralExp();
    AssocArrayLiteralExp* isAssocArrayLiteralExp();
    StructLiteralExp* isStructLiteralExp();
    CompoundLiteralExp* isCompoundLiteralExp();
    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();
    ThrowExp* isThrowExp();
    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();
    LoweredAssignExp* isLoweredAssignExp();
    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();
    GenericExp* isGenericExp();
    DefaultInitExp* isDefaultInitExp();
    FileInitExp* isFileInitExp();
    LineInitExp* isLineInitExp();
    ModuleInitExp* isModuleInitExp();
    FuncInitExp* isFuncInitExp();
    PrettyFuncInitExp* isPrettyFuncInitExp();
    ObjcClassReferenceExp* isObjcClassReferenceExp();
    ClassReferenceExp* isClassReferenceExp();
    ThrownExceptionExp* isThrownExceptionExp();
    UnaExp* isUnaExp();
    BinExp* isBinExp();
    BinAssignExp* isBinAssignExp();
    void accept(Visitor* v) override;
};

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

class BinAssignExp : public BinExp
{
public:
    bool isLvalue() final override;
    void accept(Visitor* v) override;
};

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

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

class UnaExp : public Expression
{
public:
    Expression* e1;
    UnaExp* syntaxCopy() override;
    void setNoderefOperand();
    void accept(Visitor* v) override;
};

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

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

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

struct ArgumentList final
{
    Array<Expression* >* arguments;
    Array<Identifier* >* names;
    ArgumentList() :
        arguments(),
        names()
    {
    }
    ArgumentList(Array<Expression* >* arguments, Array<Identifier* >* names = nullptr) :
        arguments(arguments),
        names(names)
        {}
};

class ArrayExp final : public UnaExp
{
public:
    Array<Expression* >* arguments;
    size_t currentDimension;
    VarDeclaration* lengthVar;
    ArrayExp* syntaxCopy() override;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

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

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

class ArrayLiteralExp final : public Expression
{
public:
    OwnedBy ownedByCtfe;
    bool onstack;
    Expression* basis;
    Array<Expression* >* elements;
    static ArrayLiteralExp* create(const Loc& loc, Array<Expression* >* elements);
    ArrayLiteralExp* syntaxCopy() override;
    bool equals(const RootObject* const o) const override;
    Expression* getElement(size_t i);
    Optional<bool > toBool() override;
    StringExp* toStringExp() override;
    void accept(Visitor* v) override;
};

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

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

class AssignExp : public BinExp
{
public:
    MemorySet memset;
    AssignExp(const Loc& loc, EXP tok, Expression* e1, Expression* e2);
    bool isLvalue() final override;
    void accept(Visitor* v) override;
};

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

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

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

class CallExp final : public UnaExp
{
public:
    Array<Expression* >* arguments;
    Array<Identifier* >* names;
    FuncDeclaration* f;
    bool directcall;
    bool inDebugStatement;
    bool ignoreAttributes;
    bool isUfcsRewrite;
    VarDeclaration* vthis2;
    static CallExp* create(const Loc& loc, Expression* e, Array<Expression* >* exps);
    static CallExp* create(const Loc& loc, Expression* e);
    static CallExp* create(const Loc& loc, Expression* e, Expression* earg1);
    static CallExp* create(const Loc& loc, FuncDeclaration* fd, Expression* earg1);
    CallExp* syntaxCopy() override;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class CastExp final : public UnaExp
{
public:
    Type* to;
    uint8_t mod;
    CastExp* syntaxCopy() override;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

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

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

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

class CatExp final : public BinExp
{
public:
    Expression* lowering;
    void accept(Visitor* v) override;
};

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

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

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

class CommaExp final : public BinExp
{
public:
    const bool isGenerated;
    bool allowCommaExp;
    bool isLvalue() override;
    Optional<bool > toBool() override;
    void accept(Visitor* v) override;
    static void allow(Expression* exp);
};

class ComplexExp final : public Expression
{
public:
    complex_t value;
    static ComplexExp* create(const Loc& loc, complex_t value, Type* type);
    bool equals(const RootObject* const o) const override;
    bool isIdentical(const Expression* const e) const override;
    dinteger_t toInteger() override;
    uinteger_t toUInteger() override;
    _d_real toReal() override;
    _d_real toImaginary() override;
    complex_t toComplex() override;
    Optional<bool > toBool() override;
    void accept(Visitor* v) override;
};

class CompoundLiteralExp final : public Expression
{
public:
    Initializer* initializer;
    void accept(Visitor* v) override;
};

class CondExp final : public BinExp
{
public:
    Expression* econd;
    CondExp* syntaxCopy() override;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

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

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

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

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

class DelegateFuncptrExp final : public UnaExp
{
public:
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class DelegatePtrExp final : public UnaExp
{
public:
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class DeleteExp final : public UnaExp
{
public:
    bool isRAII;
    void accept(Visitor* v) override;
};

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

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

class IdentifierExp : public Expression
{
public:
    Identifier* ident;
    static IdentifierExp* create(const Loc& loc, Identifier* ident);
    bool isLvalue() final override;
    void accept(Visitor* v) override;
};

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

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

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

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

class DotTemplateInstanceExp final : public UnaExp
{
public:
    TemplateInstance* ti;
    DotTemplateInstanceExp* syntaxCopy() override;
    bool checkType() override;
    bool checkValue() override;
    void accept(Visitor* v) override;
};

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

class DotVarExp final : public UnaExp
{
public:
    Declaration* var;
    bool hasOverloads;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class DsymbolExp final : public Expression
{
public:
    Dsymbol* s;
    bool hasOverloads;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

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

class ErrorExp final : public Expression
{
public:
    static ErrorExp* get();
    void accept(Visitor* v) override;
    static ErrorExp* errorexp;
};

class FileInitExp final : public DefaultInitExp
{
public:
    void accept(Visitor* v) override;
};

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

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

class FuncInitExp final : public DefaultInitExp
{
public:
    void accept(Visitor* v) override;
};

class GenericExp final : public Expression
{
public:
    Expression* cntlExp;
    Array<Type* >* types;
    Array<Expression* >* exps;
    GenericExp* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

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

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

class IndexExp final : public BinExp
{
public:
    VarDeclaration* lengthVar;
    bool modifiable;
    bool indexIsInBounds;
    IndexExp* syntaxCopy() override;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class IntegerExp final : public Expression
{
    dinteger_t value;
public:
    static IntegerExp* create(const Loc& loc, dinteger_t value, Type* type);
    bool equals(const RootObject* const o) const override;
    dinteger_t toInteger() override;
    _d_real toReal() override;
    _d_real toImaginary() override;
    complex_t toComplex() override;
    Optional<bool > toBool() override;
    void accept(Visitor* v) override;
    dinteger_t getInteger();
    IntegerExp* syntaxCopy() override;
    static IntegerExp* createBool(bool b);
};

class InterpExp final : public Expression
{
public:
    char postfix;
    OwnedBy ownedByCtfe;
    InterpolatedSet* interpolatedSet;
    enum : char { NoPostfix = 0u };

    void accept(Visitor* v) override;
};

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

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

enum : bool { LOGSEMANTIC = false };

class LineInitExp final : public DefaultInitExp
{
public:
    void accept(Visitor* v) override;
};

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

class LoweredAssignExp final : public AssignExp
{
public:
    Expression* lowering;
    const char* toChars() const override;
    void accept(Visitor* v) override;
};

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

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

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

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

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

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

enum class ModifyFlags
{
    none = 0,
    noError = 1,
    fieldAssign = 2,
};

class ModuleInitExp final : public DefaultInitExp
{
public:
    void accept(Visitor* v) override;
};

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

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

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

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

class NewExp final : public Expression
{
public:
    Expression* thisexp;
    Type* newtype;
    Array<Expression* >* arguments;
    Array<Identifier* >* names;
    Expression* argprefix;
    CtorDeclaration* member;
    bool onstack;
    bool thrownew;
    Expression* lowering;
    static NewExp* create(const Loc& loc, Expression* thisexp, Type* newtype, Array<Expression* >* arguments);
    NewExp* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

class NullExp final : public Expression
{
public:
    bool equals(const RootObject* const o) const override;
    Optional<bool > toBool() override;
    StringExp* toStringExp() override;
    void accept(Visitor* v) override;
};

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

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

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

class OverExp final : public Expression
{
public:
    OverloadSet* vars;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

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

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

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

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

class PrettyFuncInitExp final : public DefaultInitExp
{
public:
    void accept(Visitor* v) override;
};

class PtrExp final : public UnaExp
{
public:
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class RealExp final : public Expression
{
public:
    _d_real value;
    static RealExp* create(const Loc& loc, _d_real value, Type* type);
    bool equals(const RootObject* const o) const override;
    bool isIdentical(const Expression* const e) const override;
    dinteger_t toInteger() override;
    uinteger_t toUInteger() override;
    _d_real toReal() override;
    _d_real toImaginary() override;
    complex_t toComplex() override;
    Optional<bool > toBool() override;
    void accept(Visitor* v) override;
};

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

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

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

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

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

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

class SliceExp final : public UnaExp
{
public:
    Expression* upr;
    Expression* lwr;
    VarDeclaration* lengthVar;
private:
    struct BitFields final
    {
        bool upperIsInBounds;
        bool lowerIsLessThanUpper;
        bool arrayop;
        BitFields() :
            upperIsInBounds(),
            lowerIsLessThanUpper(),
            arrayop()
        {
        }
        BitFields(bool upperIsInBounds, bool lowerIsLessThanUpper = false, bool arrayop = false) :
            upperIsInBounds(upperIsInBounds),
            lowerIsLessThanUpper(lowerIsLessThanUpper),
            arrayop(arrayop)
            {}
    };

public:
    bool upperIsInBounds() const;
    bool upperIsInBounds(bool v);
    bool lowerIsLessThanUpper() const;
    bool lowerIsLessThanUpper(bool v);
    bool arrayop() const;
    bool arrayop(bool v);
private:
    uint8_t bitFields;
public:
    SliceExp* syntaxCopy() override;
    bool isLvalue() override;
    Optional<bool > toBool() override;
    void accept(Visitor* v) override;
};

class StringExp final : public Expression
{
public:
    char postfix;
    OwnedBy ownedByCtfe;
    union
    {
        char* string;
        char16_t* wstring;
        char32_t* dstring;
        uint64_t* lstring;
    };
    size_t len;
    uint8_t sz;
    bool committed;
    bool hexString;
    enum : char { NoPostfix = 0u };

    static StringExp* create(const Loc& loc, const char* s);
    static StringExp* create(const Loc& loc, const void* string, size_t len);
    bool equals(const RootObject* const o) const override;
    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;
    dinteger_t getIndex(size_t i) const;
    StringExp* toStringExp() override;
    int32_t compare(const StringExp* const se2) const;
    Optional<bool > toBool() override;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class StructLiteralExp final : public Expression
{
public:
    StructDeclaration* sd;
    Array<Expression* >* elements;
    Type* stype;
    union
    {
        void* sym;
        StructLiteralExp* inlinecopy;
    };
    StructLiteralExp* origin;
    uint8_t stageflags;
    bool useStaticInit;
    bool isOriginal;
    OwnedBy ownedByCtfe;
    static StructLiteralExp* create(const Loc& loc, StructDeclaration* sd, void* elements, Type* stype = nullptr);
    bool equals(const RootObject* const o) const override;
    StructLiteralExp* syntaxCopy() override;
    void accept(Visitor* v) override;
};

class ThisExp : public Expression
{
public:
    VarDeclaration* var;
    ThisExp(const Loc& loc, const EXP tok);
    ThisExp* syntaxCopy() override;
    Optional<bool > toBool() override;
    bool isLvalue() final override;
    void accept(Visitor* v) override;
};

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

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

class SymOffExp final : public SymbolExp
{
public:
    dinteger_t offset;
    Optional<bool > toBool() override;
    void accept(Visitor* v) override;
};

class TemplateExp final : public Expression
{
public:
    TemplateDeclaration* td;
    FuncDeclaration* fd;
    bool isLvalue() override;
    bool checkType() override;
    bool checkValue() override;
    void accept(Visitor* v) override;
};

class ThrowExp final : public UnaExp
{
public:
    ThrowExp* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

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

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

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

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

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

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

class VarExp final : public SymbolExp
{
public:
    bool delegateWasExtracted;
    static VarExp* create(const Loc& loc, Declaration* var, bool hasOverloads = true);
    bool equals(const RootObject* const o) const override;
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class VectorArrayExp final : public UnaExp
{
public:
    bool isLvalue() override;
    void accept(Visitor* v) override;
};

class VectorExp final : public UnaExp
{
public:
    TypeVector* to;
    uint32_t dim;
    OwnedBy ownedByCtfe;
    static VectorExp* create(const Loc& loc, Expression* e, Type* t);
    VectorExp* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

enum : int32_t { WANTexpand = 1 };

enum : int32_t { WANTvalue = 0 };

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

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

enum : int32_t { stageApply = 8 };

enum : int32_t { stageInlineScan = 16 };

enum : int32_t { stageOptimize = 4 };

enum : int32_t { stageScrub = 1 };

enum : int32_t { stageSearchPointers = 2 };

enum : int32_t { stageToCBuffer = 32 };

struct AttributeViolation final
{
    Loc loc;
    const char* fmtStr;
    RootObject* arg0;
    RootObject* arg1;
    RootObject* arg2;
    AttributeViolation() :
        loc(Loc(0u, 0u, 0u)),
        fmtStr(nullptr),
        arg0(nullptr),
        arg1(nullptr),
        arg2(nullptr)
    {
    }
    AttributeViolation(Loc loc, const char* fmtStr = nullptr, RootObject* arg0 = nullptr, RootObject* arg1 = nullptr, RootObject* arg2 = nullptr) :
        loc(loc),
        fmtStr(fmtStr),
        arg0(arg0),
        arg1(arg1),
        arg2(arg2)
        {}
};

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

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

struct ObjcFuncDeclaration final
{
    ObjcSelector* selector;
    VarDeclaration* selectorParameter;
    bool isOptional;
    ObjcFuncDeclaration() :
        selector(),
        selectorParameter(),
        isOptional()
    {
    }
    ObjcFuncDeclaration(ObjcSelector* selector, VarDeclaration* selectorParameter = nullptr, bool isOptional = false) :
        selector(selector),
        selectorParameter(selectorParameter),
        isOptional(isOptional)
        {}
};

enum class PURE : uint8_t
{
    impure = 0u,
    fwdref = 1u,
    weak = 2u,
    const_ = 3u,
};

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

struct ParameterList final
{
    Array<Parameter* >* parameters;
    StorageClass stc;
    VarArg varargs;
    bool hasIdentifierList;
    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),
        hasIdentifierList()
    {
    }
};

class FuncDeclaration : public Declaration
{
public:
    Statement* fbody;
    Array<FuncDeclaration* > foverrides;
private:
    ContractInfo* contracts;
public:
    const char* mangleString;
    VarDeclaration* vresult;
    LabelDsymbol* returnLabel;
    void* isTypeIsolatedCache;
    DsymbolTable* localsymtab;
    VarDeclaration* vthis;
    VarDeclaration* v_arguments;
    VarDeclaration* v_argptr;
    Array<VarDeclaration* >* parameters;
    DsymbolTable* labtab;
    Dsymbol* overnext;
    FuncDeclaration* overnext0;
    Loc endloc;
    int32_t vtblIndex;
    ILS inlineStatusStmt;
    ILS inlineStatusExp;
    PINLINE inlining;
    int32_t inlineNest;
    ForeachStatement* fes;
    BaseClass* interfaceVirtual;
    Type* tintro;
    StorageClass storage_class2;
    int32_t hasReturnExp;
    VarDeclaration* nrvo_var;
    Symbol* shidden;
    Array<ReturnStatement* >* returns;
    Array<GotoStatement* >* gotos;
    Array<VarDeclaration* >* alignSectionVars;
    Symbol* salignSection;
    BUILTIN builtin;
    int32_t tookAddressOf;
    bool requiresClosure;
    Array<VarDeclaration* > closureVars;
    Array<VarDeclaration* > outerVars;
    Array<FuncDeclaration* > siblingCallers;
    Array<FuncDeclaration* >* inlinedNestedCallees;
    AttributeViolation* safetyViolation;
    AttributeViolation* nogcViolation;
    AttributeViolation* pureViolation;
    AttributeViolation* nothrowViolation;
    bool purityInprocess() const;
    bool purityInprocess(bool v);
    bool safetyInprocess() const;
    bool safetyInprocess(bool v);
    bool nothrowInprocess() const;
    bool nothrowInprocess(bool v);
    bool nogcInprocess() const;
    bool nogcInprocess(bool v);
    bool returnInprocess() const;
    bool returnInprocess(bool v);
    bool inlineScanned() const;
    bool inlineScanned(bool v);
    bool inferScope() const;
    bool inferScope(bool v);
    bool hasCatches() const;
    bool hasCatches(bool v);
    bool skipCodegen() const;
    bool skipCodegen(bool v);
    bool printf() const;
    bool printf(bool v);
    bool scanf() const;
    bool scanf(bool v);
    bool noreturn() const;
    bool noreturn(bool v);
    bool isNRVO() const;
    bool isNRVO(bool v);
    bool isNaked() const;
    bool isNaked(bool v);
    bool isGenerated() const;
    bool isGenerated(bool v);
    bool isIntroducing() const;
    bool isIntroducing(bool v);
    bool hasSemantic3Errors() const;
    bool hasSemantic3Errors(bool v);
    bool hasNoEH() const;
    bool hasNoEH(bool v);
    bool inferRetType() const;
    bool inferRetType(bool v);
    bool hasDualContext() const;
    bool hasDualContext(bool v);
    bool hasAlwaysInlines() const;
    bool hasAlwaysInlines(bool v);
    bool isCrtCtor() const;
    bool isCrtCtor(bool v);
    bool isCrtDtor() const;
    bool isCrtDtor(bool v);
    bool hasEscapingSiblings() const;
    bool hasEscapingSiblings(bool v);
    bool computedEscapingSiblings() const;
    bool computedEscapingSiblings(bool v);
    bool dllImport() const;
    bool dllImport(bool v);
    bool dllExport() const;
    bool dllExport(bool v);
private:
    uint32_t bitFields;
public:
    ObjcFuncDeclaration objc;
    static FuncDeclaration* create(const Loc& loc, const Loc& endloc, Identifier* id, StorageClass storage_class, Type* type, bool noreturn = false);
    Array<Statement* >* frequires();
    Array<Ensure >* fensures();
    Statement* frequire();
    Statement* fensure();
    FuncDeclaration* fdrequire();
    FuncDeclaration* fdensure();
    Array<Expression* >* fdrequireParams();
    Array<Expression* >* fdensureParams();
    Array<Statement* >* frequires(Array<Statement* >* param);
    Array<Ensure >* fensures(Array<Ensure >* param);
    Statement* frequire(Statement* param);
    Statement* fensure(Statement* param);
    FuncDeclaration* fdrequire(FuncDeclaration* param);
    FuncDeclaration* fdensure(FuncDeclaration* param);
    Array<Expression* >* fdrequireParams(Array<Expression* >* param);
    Array<Expression* >* fdensureParams(Array<Expression* >* param);
    FuncDeclaration* syntaxCopy(Dsymbol* s) override;
    bool equals(const RootObject* const o) const final override;
    bool overloadInsert(Dsymbol* s) override;
    bool inUnittest();
    static MATCH leastAsSpecialized(FuncDeclaration* f, FuncDeclaration* g, Array<Identifier* >* names);
    LabelDsymbol* searchLabel(Identifier* ident, const Loc& loc);
    enum : int32_t { LevelError = -2 };

    const char* toPrettyChars(bool QualifyTypes = false) override;
    const char* toFullSignature();
    bool isMain() const;
    bool isCMain() const;
    bool isWinMain() const;
    bool isDllMain() const;
    bool isRtInit() const;
    bool isExport() const final override;
    bool isImportedSymbol() const final override;
    bool isCodeseg() const final override;
    bool isOverloadable() const final override;
    bool isAbstract() final override;
    bool canInferAttributes(Scope* sc);
    void initInferAttributes();
    PURE isPure();
    bool isSafe();
    bool isTrusted();
    bool isNogc();
    virtual bool isNested() const;
    AggregateDeclaration* isThis() override;
    bool needThis() final override;
    bool isVirtualMethod();
    virtual bool isVirtual() const;
    bool isFinalFunc() const;
    virtual bool addPreInvariant();
    virtual bool addPostInvariant();
    const char* kind() const override;
    bool isUnique() const;
    bool needsClosure();
    bool checkClosure();
    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);
    FuncDeclaration* isFuncDeclaration() final override;
    virtual FuncDeclaration* toAliasFunc();
    void accept(Visitor* v) override;
};

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

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

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

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

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

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

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

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

class SharedStaticCtorDeclaration final : public StaticCtorDeclaration
{
public:
    bool standalone;
    SharedStaticCtorDeclaration* syntaxCopy(Dsymbol* s) override;
    SharedStaticCtorDeclaration* isSharedStaticCtorDeclaration() override;
    void accept(Visitor* v) override;
};

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

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

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

struct HdrGenState final
{
    bool hdrgen;
    bool ddoc;
    bool fullDump;
    bool importcHdr;
    bool doFuncBodies;
    bool vcg_ast;
    bool skipConstraints;
    bool fullQual;
    int32_t tpltMember;
    int32_t autoMember;
    int32_t forStmtInit;
    int32_t insideFuncBody;
    int32_t insideAggregate;
    bool declstring;
    EnumDeclaration* inEnumDecl;
    HdrGenState() :
        hdrgen(),
        ddoc(),
        fullDump(),
        importcHdr(),
        doFuncBodies(),
        vcg_ast(),
        skipConstraints(),
        fullQual(),
        tpltMember(),
        autoMember(),
        forStmtInit(),
        insideFuncBody(),
        insideAggregate(),
        declstring(),
        inEnumDecl()
    {
    }
    HdrGenState(bool hdrgen, bool ddoc = false, bool fullDump = false, bool importcHdr = false, bool doFuncBodies = false, bool vcg_ast = false, bool skipConstraints = false, bool fullQual = false, int32_t tpltMember = 0, int32_t autoMember = 0, int32_t forStmtInit = 0, int32_t insideFuncBody = 0, int32_t insideAggregate = 0, bool declstring = false, EnumDeclaration* inEnumDecl = nullptr) :
        hdrgen(hdrgen),
        ddoc(ddoc),
        fullDump(fullDump),
        importcHdr(importcHdr),
        doFuncBodies(doFuncBodies),
        vcg_ast(vcg_ast),
        skipConstraints(skipConstraints),
        fullQual(fullQual),
        tpltMember(tpltMember),
        autoMember(autoMember),
        forStmtInit(forStmtInit),
        insideFuncBody(insideFuncBody),
        insideAggregate(insideAggregate),
        declstring(declstring),
        inEnumDecl(inEnumDecl)
        {}
};

enum : int32_t { TEST_EMIT_ALL = 0 };

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

class Initializer : public ASTNode
{
public:
    Loc loc;
    InitKind kind;
    DYNCAST dyncast() const override;
    ErrorInitializer* isErrorInitializer();
    VoidInitializer* isVoidInitializer();
    DefaultInitializer* isDefaultInitializer();
    StructInitializer* isStructInitializer();
    ArrayInitializer* isArrayInitializer();
    ExpInitializer* isExpInitializer();
    CInitializer* isCInitializer();
    void accept(Visitor* v) override;
};

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

class CInitializer final : public Initializer
{
public:
    Array<DesigInit > initializerList;
    Type* type;
    bool sem;
    void accept(Visitor* v) override;
};

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

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

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

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

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

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

enum class Covariant
{
    distinct = 0,
    yes = 1,
    no = 2,
    fwdref = 3,
};

enum class DotExpFlag
{
    none = 0,
    gag = 1,
    noDeref = 2,
    noAliasThis = 4,
};

enum : int32_t { LOGDEFAULTINIT = 0 };

enum : int32_t { LOGDOTEXP = 0 };

class Parameter final : public ASTNode
{
public:
    Loc loc;
    StorageClass storageClass;
    Type* type;
    Identifier* ident;
    Expression* defaultArg;
    UserAttributeDeclaration* userAttribDecl;
    static Parameter* create(const Loc& loc, StorageClass storageClass, Type* type, Identifier* ident, Expression* defaultArg, UserAttributeDeclaration* userAttribDecl);
    Parameter* syntaxCopy();
    Type* isLazyArray();
    bool isLazy() const;
    bool isReference() const;
    DYNCAST dyncast() const override;
    void accept(Visitor* v) override;
    static size_t dim(Array<Parameter* >* parameters);
    static Parameter* getNth(Array<Parameter* >* parameters, size_t nth);
    const char* toChars() const override;
    bool isCovariant(bool returnByRef, const Parameter* const p) const;
};

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

enum : uint64_t { SIZE_INVALID = 18446744073709551615LLU };

enum class ScopeRef
{
    None = 0,
    Scope = 1,
    ReturnScope = 2,
    Ref = 3,
    ReturnRef = 4,
    RefScope = 5,
    ReturnRef_Scope = 6,
    Ref_ReturnScope = 7,
    Return = 8,
};

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

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

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

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

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

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

class TypeClass final : public Type
{
public:
    ClassDeclaration* sym;
    AliasThisRec att;
    CPPMANGLE cppmangle;
    const char* kind() const override;
    uinteger_t size(const Loc& loc) override;
    TypeClass* syntaxCopy() override;
    ClassDeclaration* isClassHandle() override;
    MATCH implicitConvTo(Type* to) override;
    MATCH constConv(Type* to) override;
    uint8_t deduceWild(Type* t, bool isRef) override;
    bool isZeroInit(const Loc& loc) override;
    bool isscope() override;
    bool isBoolean() override;
    void accept(Visitor* v) override;
};

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

class TypeDelegate final : public TypeNext
{
public:
    static TypeDelegate* create(TypeFunction* t);
    const char* kind() const override;
    TypeDelegate* syntaxCopy() override;
    uinteger_t size(const Loc& loc) override;
    uint32_t alignsize() override;
    MATCH implicitConvTo(Type* to) override;
    bool isZeroInit(const Loc& loc) override;
    bool isBoolean() override;
    void accept(Visitor* v) override;
};

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

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

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

class TypeFunction final : public TypeNext
{
public:
    ParameterList parameterList;
private:
    struct BitFields final
    {
        bool isnothrow;
        bool isnogc;
        bool isproperty;
        bool isref;
        bool isreturn;
        bool isScopeQual;
        bool isreturninferred;
        bool isscopeinferred;
        bool islive;
        bool incomplete;
        bool isInOutParam;
        bool isInOutQual;
        bool isctor;
        bool isreturnscope;
        BitFields() :
            isnothrow(),
            isnogc(),
            isproperty(),
            isref(),
            isreturn(),
            isScopeQual(),
            isreturninferred(),
            isscopeinferred(),
            islive(),
            incomplete(),
            isInOutParam(),
            isInOutQual(),
            isctor(),
            isreturnscope()
        {
        }
        BitFields(bool isnothrow, bool isnogc = false, bool isproperty = false, bool isref = false, bool isreturn = false, bool isScopeQual = false, bool isreturninferred = false, bool isscopeinferred = false, bool islive = false, bool incomplete = false, bool isInOutParam = false, bool isInOutQual = false, bool isctor = false, bool isreturnscope = false) :
            isnothrow(isnothrow),
            isnogc(isnogc),
            isproperty(isproperty),
            isref(isref),
            isreturn(isreturn),
            isScopeQual(isScopeQual),
            isreturninferred(isreturninferred),
            isscopeinferred(isscopeinferred),
            islive(islive),
            incomplete(incomplete),
            isInOutParam(isInOutParam),
            isInOutQual(isInOutQual),
            isctor(isctor),
            isreturnscope(isreturnscope)
            {}
    };

public:
    bool isnothrow() const;
    bool isnothrow(bool v);
    bool isnogc() const;
    bool isnogc(bool v);
    bool isproperty() const;
    bool isproperty(bool v);
    bool isref() const;
    bool isref(bool v);
    bool isreturn() const;
    bool isreturn(bool v);
    bool isScopeQual() const;
    bool isScopeQual(bool v);
    bool isreturninferred() const;
    bool isreturninferred(bool v);
    bool isscopeinferred() const;
    bool isscopeinferred(bool v);
    bool islive() const;
    bool islive(bool v);
    bool incomplete() const;
    bool incomplete(bool v);
    bool isInOutParam() const;
    bool isInOutParam(bool v);
    bool isInOutQual() const;
    bool isInOutQual(bool v);
    bool isctor() const;
    bool isctor(bool v);
    bool isreturnscope() const;
    bool isreturnscope(bool v);
private:
    uint16_t bitFields;
public:
    LINK linkage;
    TRUST trust;
    PURE purity;
    int8_t inuse;
    ArgumentList inferenceArguments;
    static TypeFunction* create(Array<Parameter* >* parameters, Type* treturn, uint8_t varargs, LINK linkage, StorageClass stc = 0);
    const char* kind() const override;
    TypeFunction* syntaxCopy() override;
    bool hasLazyParameters();
    bool isDstyleVariadic() const;
    MATCH constConv(Type* to) override;
    bool iswild() const;
    void accept(Visitor* v) override;
};

class TypeQualified : public Type
{
public:
    Loc loc;
    Array<RootObject* > idents;
    TypeQualified* syntaxCopy() override = 0;
    uinteger_t size(const Loc& loc) override;
    void accept(Visitor* v) override;
};

class TypeIdentifier final : public TypeQualified
{
public:
    Identifier* ident;
    Dsymbol* originalSymbol;
    static TypeIdentifier* create(const Loc& loc, Identifier* ident);
    const char* kind() const override;
    TypeIdentifier* syntaxCopy() override;
    void accept(Visitor* v) override;
};

class TypeInstance final : public TypeQualified
{
public:
    TemplateInstance* tempinst;
    const char* kind() const override;
    TypeInstance* syntaxCopy() override;
    void accept(Visitor* v) override;
};

class TypeMixin final : public Type
{
public:
    Loc loc;
    Array<Expression* >* exps;
    RootObject* obj;
    const char* kind() const override;
    TypeMixin* syntaxCopy() override;
    void accept(Visitor* v) override;
};

class TypeNoreturn final : public Type
{
public:
    const char* kind() const override;
    TypeNoreturn* syntaxCopy() override;
    MATCH implicitConvTo(Type* to) override;
    MATCH constConv(Type* to) override;
    bool isBoolean() override;
    uinteger_t size(const Loc& loc) override;
    uint32_t alignsize() override;
    void accept(Visitor* v) override;
};

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

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

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

class TypeReturn final : public TypeQualified
{
public:
    const char* kind() const override;
    TypeReturn* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

class TypeStruct final : public Type
{
public:
    StructDeclaration* sym;
    AliasThisRec att;
    bool inuse;
    static TypeStruct* create(StructDeclaration* sym);
    const char* kind() const override;
    uinteger_t size(const Loc& loc) override;
    uint32_t alignsize() override;
    TypeStruct* syntaxCopy() override;
    structalign_t alignment() override;
    Expression* defaultInitLiteral(const Loc& loc) override;
    bool isZeroInit(const Loc& loc) override;
    bool isAssignable() override;
    bool isBoolean() override;
    bool needsDestruction() override;
    bool needsCopyOrPostblit() override;
    bool needsNested() override;
    bool hasVoidInitPointers() override;
    bool hasSystemFields() override;
    bool hasInvariant() override;
    MATCH implicitConvTo(Type* to) override;
    MATCH constConv(Type* to) override;
    uint8_t deduceWild(Type* t, bool isRef) override;
    void accept(Visitor* v) override;
};

class TypeTag final : public Type
{
public:
    Loc loc;
    TOK tok;
    structalign_t packalign;
    Identifier* id;
    Type* base;
    Array<Dsymbol* >* members;
    Type* resolved;
    uint8_t mod;
    const char* kind() const override;
    TypeTag* syntaxCopy() override;
    void accept(Visitor* v) override;
};

class TypeTraits final : public Type
{
public:
    Loc loc;
    TraitsExp* exp;
    RootObject* obj;
    const char* kind() const override;
    TypeTraits* syntaxCopy() override;
    void accept(Visitor* v) override;
    uinteger_t size(const Loc& loc) override;
};

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 override;
    TypeTuple* syntaxCopy() override;
    bool equals(const RootObject* const o) const override;
    MATCH implicitConvTo(Type* to) override;
    void accept(Visitor* v) override;
};

class TypeTypeof final : public TypeQualified
{
public:
    Expression* exp;
    int32_t inuse;
    const char* kind() const override;
    TypeTypeof* syntaxCopy() override;
    uinteger_t size(const Loc& loc) override;
    void accept(Visitor* v) override;
};

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

class Nspace final : public ScopeDsymbol
{
public:
    Expression* identExp;
    Nspace* syntaxCopy(Dsymbol* s) override;
    bool hasPointers() override;
    const char* kind() const override;
    Nspace* isNspace() override;
    void accept(Visitor* v) override;
};

enum class STMT : uint8_t
{
    Error = 0u,
    Peel = 1u,
    Exp = 2u,
    DtorExp = 3u,
    Mixin = 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 final override;
    virtual Statement* syntaxCopy();
    static Array<Statement* >* arraySyntaxCopy(Array<Statement* >* a);
    virtual Statement* getRelatedLabeled();
    virtual bool hasBreak() const;
    virtual bool hasContinue() const;
    virtual Statement* last();
    void accept(Visitor* v) override;
    virtual ReturnStatement* endsWithReturnStatement();
    ErrorStatement* isErrorStatement();
    PeelStatement* isPeelStatement();
    ScopeStatement* isScopeStatement();
    ExpStatement* isExpStatement();
    CompoundStatement* isCompoundStatement();
    ReturnStatement* isReturnStatement();
    IfStatement* isIfStatement();
    ConditionalStatement* isConditionalStatement();
    StaticForeachStatement* isStaticForeachStatement();
    CaseStatement* isCaseStatement();
    DefaultStatement* isDefaultStatement();
    LabelStatement* isLabelStatement();
    GotoStatement* isGotoStatement();
    GotoDefaultStatement* isGotoDefaultStatement();
    GotoCaseStatement* isGotoCaseStatement();
    BreakStatement* isBreakStatement();
    DtorExpStatement* isDtorExpStatement();
    MixinStatement* isMixinStatement();
    ForwardingStatement* isForwardingStatement();
    DoStatement* isDoStatement();
    WhileStatement* isWhileStatement();
    ForStatement* isForStatement();
    ForeachStatement* isForeachStatement();
    SwitchStatement* isSwitchStatement();
    ContinueStatement* isContinueStatement();
    WithStatement* isWithStatement();
    TryCatchStatement* isTryCatchStatement();
    ThrowStatement* isThrowStatement();
    DebugStatement* isDebugStatement();
    TryFinallyStatement* isTryFinallyStatement();
    ScopeGuardStatement* isScopeGuardStatement();
    SwitchErrorStatement* isSwitchErrorStatement();
    UnrolledLoopStatement* isUnrolledLoopStatement();
    ForeachRangeStatement* isForeachRangeStatement();
    CompoundDeclarationStatement* isCompoundDeclarationStatement();
    CompoundAsmStatement* isCompoundAsmStatement();
    PragmaStatement* isPragmaStatement();
    StaticAssertStatement* isStaticAssertStatement();
    CaseRangeStatement* isCaseRangeStatement();
    SynchronizedStatement* isSynchronizedStatement();
    AsmStatement* isAsmStatement();
    InlineAsmStatement* isInlineAsmStatement();
    GccAsmStatement* isGccAsmStatement();
    ImportStatement* isImportStatement();
};

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

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

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

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

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

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

class CompoundAsmStatement final : public CompoundStatement
{
public:
    StorageClass stc;
    CompoundAsmStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

class ConditionalStatement final : public Statement
{
public:
    Condition* condition;
    Statement* ifbody;
    Statement* elsebody;
    ConditionalStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

class DebugStatement final : public Statement
{
public:
    Statement* statement;
    DebugStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

class ExpStatement : public Statement
{
public:
    Expression* exp;
    static ExpStatement* create(const Loc& loc, Expression* exp);
    ExpStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

class ForStatement final : public Statement
{
public:
    Statement* _init;
    Expression* condition;
    Expression* increment;
    Statement* _body;
    Loc endloc;
    Statement* relatedLabeled;
    ForStatement* syntaxCopy() override;
    Statement* getRelatedLabeled() override;
    bool hasBreak() const override;
    bool hasContinue() const override;
    void accept(Visitor* v) override;
};

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

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;
    ForeachStatement* syntaxCopy() override;
    bool hasBreak() const override;
    bool hasContinue() const override;
    void accept(Visitor* v) override;
};

class ForwardingStatement final : public Statement
{
public:
    ForwardingScopeDsymbol* sym;
    Statement* statement;
    ForwardingStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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;
    GccAsmStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

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

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

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

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

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

class LabelStatement final : public Statement
{
public:
    Identifier* ident;
    Statement* statement;
    Statement* tryBody;
    TryFinallyStatement* tf;
    ScopeGuardStatement* os;
    VarDeclaration* lastVar;
    Statement* gotoTarget;
    void* extra;
    bool breaks;
    bool inCtfeBlock;
    LabelStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

class MixinStatement final : public Statement
{
public:
    Array<Expression* >* exps;
    MixinStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

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

class ScopeGuardStatement final : public Statement
{
public:
    TOK tok;
    Statement* statement;
    ScopeGuardStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

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

class StaticForeachStatement final : public Statement
{
public:
    StaticForeach* sfe;
    StaticForeachStatement* syntaxCopy() override;
    void accept(Visitor* v) override;
};

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

class SwitchStatement final : public Statement
{
public:
    Parameter* param;
    Expression* condition;
    Statement* _body;
    bool isFinal;
    Loc endloc;
    bool hasDefault;
    bool hasVars;
    DefaultStatement* sdefault;
    Statement* tryBody;
    TryFinallyStatement* tf;
    Array<GotoCaseStatement* > gotoCases;
    Array<CaseStatement* >* cases;
    VarDeclaration* lastVar;
    SwitchStatement* syntaxCopy() override;
    bool hasBreak() const override;
    void accept(Visitor* v) override;
};

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

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

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

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

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

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

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

class StaticAssert final : public Dsymbol
{
public:
    Expression* exp;
    Array<Expression* >* msgs;
    StaticAssert* syntaxCopy(Dsymbol* s) override;
    bool oneMember(Dsymbol*& ps, Identifier* ident) override;
    const char* kind() const override;
    StaticAssert* isStaticAssert() override;
    void accept(Visitor* v) override;
};

struct UnionExp final
{
    #pragma pack(push, 8)
private:
    union _AnonStruct_u
    {
        char exp[30LLU];
        char integerexp[40LLU];
        char errorexp[30LLU];
        char realexp[48LLU];
        char complexexp[64LLU];
        char symoffexp[64LLU];
        char stringexp[51LLU];
        char arrayliteralexp[48LLU];
        char assocarrayliteralexp[56LLU];
        char structliteralexp[76LLU];
        char compoundliteralexp[40LLU];
        char nullexp[30LLU];
        char dotvarexp[49LLU];
        char addrexp[40LLU];
        char indexexp[74LLU];
        char sliceexp[65LLU];
        char vectorexp[53LLU];
    };
    #pragma pack(pop)

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

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

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 = 32768LLU,
    constscoperef = 65536LLU,
    templateparameter = 131072LLU,
    ref_ = 262144LLU,
    scope_ = 524288LLU,
    scopeinferred = 2097152LLU,
    return_ = 4194304LLU,
    returnScope = 8388608LLU,
    returninferred = 16777216LLU,
    immutable_ = 33554432LLU,
    manifest = 134217728LLU,
    nodtor = 268435456LLU,
    nothrow_ = 536870912LLU,
    pure_ = 1073741824LLU,
    tls = 2147483648LLU,
    alias_ = 4294967296LLU,
    shared_ = 8589934592LLU,
    gshared = 17179869184LLU,
    wild = 34359738368LLU,
    property = 68719476736LLU,
    safe = 137438953472LLU,
    trusted = 274877906944LLU,
    system = 549755813888LLU,
    ctfe = 1099511627776LLU,
    disable = 2199023255552LLU,
    result = 4398046511104LLU,
    nodefaultctor = 8796093022208LLU,
    temp = 17592186044416LLU,
    rvalue = 35184372088832LLU,
    nogc = 70368744177664LLU,
    autoref = 140737488355328LLU,
    inference = 281474976710656LLU,
    exptemp = 562949953421312LLU,
    future = 1125899906842624LLU,
    local = 2251799813685248LLU,
    live = 4503599627370496LLU,
    register_ = 9007199254740992LLU,
    volatile_ = 18014398509481984LLU,
    safeGroup = 962072674304LLU,
    IOR = 333824LLU,
    TYPECTOR = 42983227396LLU,
    FUNCATTR = 4575000774574080LLU,
    visibleStorageClasses = 7954966262857631LLU,
    flowThruAggregate = 962072674304LLU,
    flowThruFunction = 18446742978991225440LLU,
};

struct ASTCodegen final
{
    using AggregateDeclaration = ::AggregateDeclaration;
    using ClassKind = ::ClassKind;
    using MangleOverride = ::MangleOverride;
    using AliasThis = ::AliasThis;
    using AliasDeclarations = ::AliasDeclarations;
    using BaseClasses = ::BaseClasses;
    using CaseStatements = ::CaseStatements;
    using Catches = ::Catches;
    using ClassDeclarations = ::ClassDeclarations;
    using DesigInits = ::DesigInits;
    using Designators = ::Designators;
    using Dsymbols = ::Dsymbols;
    using DtorDeclarations = ::DtorDeclarations;
    using Ensures = ::Ensures;
    using Expressions = ::Expressions;
    using FuncDeclarations = ::FuncDeclarations;
    using GotoCaseStatements = ::GotoCaseStatements;
    using GotoStatements = ::GotoStatements;
    using Identifiers = ::Identifiers;
    using Initializers = ::Initializers;
    using Modules = ::Modules;
    using Objects = ::Objects;
    using Parameters = ::Parameters;
    using ReturnStatements = ::ReturnStatements;
    using ScopeStatements = ::ScopeStatements;
    using SharedStaticDtorDeclarations = ::SharedStaticDtorDeclarations;
    using Statements = ::Statements;
    using StaticDtorDeclarations = ::StaticDtorDeclarations;
    using Strings = ::Strings;
    using TemplateInstances = ::TemplateInstances;
    using TemplateParameters = ::TemplateParameters;
    using Types = ::Types;
    using VarDeclarations = ::VarDeclarations;
    using AlignDeclaration = ::AlignDeclaration;
    using AnonDeclaration = ::AnonDeclaration;
    using AttribDeclaration = ::AttribDeclaration;
    using CPPMangleDeclaration = ::CPPMangleDeclaration;
    using CPPNamespaceDeclaration = ::CPPNamespaceDeclaration;
    using ConditionalDeclaration = ::ConditionalDeclaration;
    using DeprecatedDeclaration = ::DeprecatedDeclaration;
    using ForwardingAttribDeclaration = ::ForwardingAttribDeclaration;
    using LinkDeclaration = ::LinkDeclaration;
    using MixinDeclaration = ::MixinDeclaration;
    using PragmaDeclaration = ::PragmaDeclaration;
    using StaticForeachDeclaration = ::StaticForeachDeclaration;
    using StaticIfDeclaration = ::StaticIfDeclaration;
    using StorageClassDeclaration = ::StorageClassDeclaration;
    using UserAttributeDeclaration = ::UserAttributeDeclaration;
    using VisibilityDeclaration = ::VisibilityDeclaration;
    using Condition = ::Condition;
    using DVCondition = ::DVCondition;
    using DebugCondition = ::DebugCondition;
    using Include = ::Include;
    using StaticForeach = ::StaticForeach;
    using StaticIfCondition = ::StaticIfCondition;
    using VersionCondition = ::VersionCondition;
    using BaseClass = ::BaseClass;
    using ClassDeclaration = ::ClassDeclaration;
    using ClassFlags = ::ClassFlags;
    using InterfaceDeclaration = ::InterfaceDeclaration;
    using AliasDeclaration = ::AliasDeclaration;
    using BitFieldDeclaration = ::BitFieldDeclaration;
    using Declaration = ::Declaration;
    using MatchAccumulator = ::MatchAccumulator;
    using OverDeclaration = ::OverDeclaration;
    using SymbolDeclaration = ::SymbolDeclaration;
    using ThisDeclaration = ::ThisDeclaration;
    using TupleDeclaration = ::TupleDeclaration;
    using TypeInfoArrayDeclaration = ::TypeInfoArrayDeclaration;
    using TypeInfoAssociativeArrayDeclaration = ::TypeInfoAssociativeArrayDeclaration;
    using TypeInfoClassDeclaration = ::TypeInfoClassDeclaration;
    using TypeInfoConstDeclaration = ::TypeInfoConstDeclaration;
    using TypeInfoDeclaration = ::TypeInfoDeclaration;
    using TypeInfoDelegateDeclaration = ::TypeInfoDelegateDeclaration;
    using TypeInfoEnumDeclaration = ::TypeInfoEnumDeclaration;
    using TypeInfoFunctionDeclaration = ::TypeInfoFunctionDeclaration;
    using TypeInfoInterfaceDeclaration = ::TypeInfoInterfaceDeclaration;
    using TypeInfoInvariantDeclaration = ::TypeInfoInvariantDeclaration;
    using TypeInfoPointerDeclaration = ::TypeInfoPointerDeclaration;
    using TypeInfoSharedDeclaration = ::TypeInfoSharedDeclaration;
    using TypeInfoStaticArrayDeclaration = ::TypeInfoStaticArrayDeclaration;
    using TypeInfoStructDeclaration = ::TypeInfoStructDeclaration;
    using TypeInfoTupleDeclaration = ::TypeInfoTupleDeclaration;
    using TypeInfoVectorDeclaration = ::TypeInfoVectorDeclaration;
    using TypeInfoWildDeclaration = ::TypeInfoWildDeclaration;
    using VarDeclaration = ::VarDeclaration;
    using EnumDeclaration = ::EnumDeclaration;
    using EnumMember = ::EnumMember;
    using Import = ::Import;
    using ForeachDg = ::ForeachDg;
    using Module = ::Module;
    using ModuleDeclaration = ::ModuleDeclaration;
    using Package = ::Package;
    using StructDeclaration = ::StructDeclaration;
    using StructFlags = ::StructFlags;
    using UnionDeclaration = ::UnionDeclaration;
    using AliasAssign = ::AliasAssign;
    using ArrayScopeSymbol = ::ArrayScopeSymbol;
    using CAsmDeclaration = ::CAsmDeclaration;
    using Dsymbol = ::Dsymbol;
    using DsymbolTable = ::DsymbolTable;
    using ExpressionDsymbol = ::ExpressionDsymbol;
    using FieldState = ::FieldState;
    using ForwardingScopeDsymbol = ::ForwardingScopeDsymbol;
    using OverloadSet = ::OverloadSet;
    using PASS = ::PASS;
    using ScopeDsymbol = ::ScopeDsymbol;
    using SearchOpt = ::SearchOpt;
    using SearchOptFlags = ::SearchOptFlags;
    using Ungag = ::Ungag;
    using Visibility = ::Visibility;
    using WithScopeSymbol = ::WithScopeSymbol;
    using MATCHpair = ::MATCHpair;
    using TemplateAliasParameter = ::TemplateAliasParameter;
    using TemplateDeclaration = ::TemplateDeclaration;
    using TemplateInstance = ::TemplateInstance;
    using TemplateInstanceBox = ::TemplateInstanceBox;
    using TemplateMixin = ::TemplateMixin;
    using TemplateParameter = ::TemplateParameter;
    using TemplatePrevious = ::TemplatePrevious;
    using TemplateStats = ::TemplateStats;
    using TemplateThisParameter = ::TemplateThisParameter;
    using TemplateTupleParameter = ::TemplateTupleParameter;
    using TemplateTypeParameter = ::TemplateTypeParameter;
    using TemplateValueParameter = ::TemplateValueParameter;
    using Tuple = ::Tuple;
    using TypeDeduced = ::TypeDeduced;
    using DebugSymbol = ::DebugSymbol;
    using VersionSymbol = ::VersionSymbol;
    using AddAssignExp = ::AddAssignExp;
    using AddExp = ::AddExp;
    using AddrExp = ::AddrExp;
    using AndAssignExp = ::AndAssignExp;
    using AndExp = ::AndExp;
    using ArgumentList = ::ArgumentList;
    using ArrayExp = ::ArrayExp;
    using ArrayLengthExp = ::ArrayLengthExp;
    using ArrayLiteralExp = ::ArrayLiteralExp;
    using AssertExp = ::AssertExp;
    using AssignExp = ::AssignExp;
    using AssocArrayLiteralExp = ::AssocArrayLiteralExp;
    using BinAssignExp = ::BinAssignExp;
    using BinExp = ::BinExp;
    using BlitExp = ::BlitExp;
    using CTFEExp = ::CTFEExp;
    using CallExp = ::CallExp;
    using CastExp = ::CastExp;
    using CatAssignExp = ::CatAssignExp;
    using CatDcharAssignExp = ::CatDcharAssignExp;
    using CatElemAssignExp = ::CatElemAssignExp;
    using CatExp = ::CatExp;
    using ClassReferenceExp = ::ClassReferenceExp;
    using CmpExp = ::CmpExp;
    using ComExp = ::ComExp;
    using CommaExp = ::CommaExp;
    using ComplexExp = ::ComplexExp;
    using CompoundLiteralExp = ::CompoundLiteralExp;
    using CondExp = ::CondExp;
    using ConstructExp = ::ConstructExp;
    using DeclarationExp = ::DeclarationExp;
    using DefaultInitExp = ::DefaultInitExp;
    using DelegateExp = ::DelegateExp;
    using DelegateFuncptrExp = ::DelegateFuncptrExp;
    using DelegatePtrExp = ::DelegatePtrExp;
    using DeleteExp = ::DeleteExp;
    using DivAssignExp = ::DivAssignExp;
    using DivExp = ::DivExp;
    using DollarExp = ::DollarExp;
    using DotExp = ::DotExp;
    using DotIdExp = ::DotIdExp;
    using DotTemplateExp = ::DotTemplateExp;
    using DotTemplateInstanceExp = ::DotTemplateInstanceExp;
    using DotTypeExp = ::DotTypeExp;
    using DotVarExp = ::DotVarExp;
    using DsymbolExp = ::DsymbolExp;
    using EqualExp = ::EqualExp;
    using ErrorExp = ::ErrorExp;
    using Expression = ::Expression;
    using FileInitExp = ::FileInitExp;
    using FuncExp = ::FuncExp;
    using FuncInitExp = ::FuncInitExp;
    using GenericExp = ::GenericExp;
    using HaltExp = ::HaltExp;
    using IdentifierExp = ::IdentifierExp;
    using IdentityExp = ::IdentityExp;
    using ImportExp = ::ImportExp;
    using InExp = ::InExp;
    using IndexExp = ::IndexExp;
    using IntegerExp = ::IntegerExp;
    using InterpExp = ::InterpExp;
    using IntervalExp = ::IntervalExp;
    using IsExp = ::IsExp;
    using LineInitExp = ::LineInitExp;
    using LogicalExp = ::LogicalExp;
    using LoweredAssignExp = ::LoweredAssignExp;
    using MemorySet = ::MemorySet;
    using MinAssignExp = ::MinAssignExp;
    using MinExp = ::MinExp;
    using MixinExp = ::MixinExp;
    using ModAssignExp = ::ModAssignExp;
    using ModExp = ::ModExp;
    using Modifiable = ::Modifiable;
    using ModifyFlags = ::ModifyFlags;
    using ModuleInitExp = ::ModuleInitExp;
    using MulAssignExp = ::MulAssignExp;
    using MulExp = ::MulExp;
    using NegExp = ::NegExp;
    using NewAnonClassExp = ::NewAnonClassExp;
    using NewExp = ::NewExp;
    using NotExp = ::NotExp;
    using NullExp = ::NullExp;
    using ObjcClassReferenceExp = ::ObjcClassReferenceExp;
    using OrAssignExp = ::OrAssignExp;
    using OrExp = ::OrExp;
    using OverExp = ::OverExp;
    using OwnedBy = ::OwnedBy;
    using PostExp = ::PostExp;
    using PowAssignExp = ::PowAssignExp;
    using PowExp = ::PowExp;
    using PreExp = ::PreExp;
    using PrettyFuncInitExp = ::PrettyFuncInitExp;
    using PtrExp = ::PtrExp;
    using RealExp = ::RealExp;
    using RemoveExp = ::RemoveExp;
    using ScopeExp = ::ScopeExp;
    using ShlAssignExp = ::ShlAssignExp;
    using ShlExp = ::ShlExp;
    using ShrAssignExp = ::ShrAssignExp;
    using ShrExp = ::ShrExp;
    using SliceExp = ::SliceExp;
    using StringExp = ::StringExp;
    using StructLiteralExp = ::StructLiteralExp;
    using SuperExp = ::SuperExp;
    using SymOffExp = ::SymOffExp;
    using SymbolExp = ::SymbolExp;
    using TemplateExp = ::TemplateExp;
    using ThisExp = ::ThisExp;
    using ThrowExp = ::ThrowExp;
    using ThrownExceptionExp = ::ThrownExceptionExp;
    using TraitsExp = ::TraitsExp;
    using TupleExp = ::TupleExp;
    using TypeExp = ::TypeExp;
    using TypeidExp = ::TypeidExp;
    using UAddExp = ::UAddExp;
    using UnaExp = ::UnaExp;
    using UshrAssignExp = ::UshrAssignExp;
    using UshrExp = ::UshrExp;
    using VarExp = ::VarExp;
    using VectorArrayExp = ::VectorArrayExp;
    using VectorExp = ::VectorExp;
    using VoidInitExp = ::VoidInitExp;
    using XorAssignExp = ::XorAssignExp;
    using XorExp = ::XorExp;
    using AttributeViolation = ::AttributeViolation;
    using BUILTIN = ::BUILTIN;
    using CtorDeclaration = ::CtorDeclaration;
    using DtorDeclaration = ::DtorDeclaration;
    using Ensure = ::Ensure;
    using FuncAliasDeclaration = ::FuncAliasDeclaration;
    using FuncDeclaration = ::FuncDeclaration;
    using FuncLiteralDeclaration = ::FuncLiteralDeclaration;
    using ILS = ::ILS;
    using InvariantDeclaration = ::InvariantDeclaration;
    using NewDeclaration = ::NewDeclaration;
    using PostBlitDeclaration = ::PostBlitDeclaration;
    using SharedStaticCtorDeclaration = ::SharedStaticCtorDeclaration;
    using SharedStaticDtorDeclaration = ::SharedStaticDtorDeclaration;
    using StaticCtorDeclaration = ::StaticCtorDeclaration;
    using StaticDtorDeclaration = ::StaticDtorDeclaration;
    using UnitTestDeclaration = ::UnitTestDeclaration;
    using HdrGenState = ::HdrGenState;
    using ArrayInitializer = ::ArrayInitializer;
    using CInitializer = ::CInitializer;
    using DefaultInitializer = ::DefaultInitializer;
    using DesigInit = ::DesigInit;
    using Designator = ::Designator;
    using ErrorInitializer = ::ErrorInitializer;
    using ExpInitializer = ::ExpInitializer;
    using Initializer = ::Initializer;
    using NeedInterpret = ::NeedInterpret;
    using StructInitializer = ::StructInitializer;
    using VisitInitializer = ::VisitInitializer;
    using VoidInitializer = ::VoidInitializer;
    using Covariant = ::Covariant;
    using DotExpFlag = ::DotExpFlag;
    using Parameter = ::Parameter;
    using ParameterList = ::ParameterList;
    using RET = ::RET;
    using ScopeRef = ::ScopeRef;
    using TRUSTformat = ::TRUSTformat;
    using Type = ::Type;
    using TypeAArray = ::TypeAArray;
    using TypeArray = ::TypeArray;
    using TypeBasic = ::TypeBasic;
    using TypeClass = ::TypeClass;
    using TypeDArray = ::TypeDArray;
    using TypeDelegate = ::TypeDelegate;
    using TypeEnum = ::TypeEnum;
    using TypeError = ::TypeError;
    using TypeFunction = ::TypeFunction;
    using TypeIdentifier = ::TypeIdentifier;
    using TypeInstance = ::TypeInstance;
    using TypeMixin = ::TypeMixin;
    using TypeNext = ::TypeNext;
    using TypeNoreturn = ::TypeNoreturn;
    using TypeNull = ::TypeNull;
    using TypePointer = ::TypePointer;
    using TypeQualified = ::TypeQualified;
    using TypeReference = ::TypeReference;
    using TypeReturn = ::TypeReturn;
    using TypeSArray = ::TypeSArray;
    using TypeSlice = ::TypeSlice;
    using TypeStruct = ::TypeStruct;
    using TypeTag = ::TypeTag;
    using TypeTraits = ::TypeTraits;
    using TypeTuple = ::TypeTuple;
    using TypeTypeof = ::TypeTypeof;
    using TypeVector = ::TypeVector;
    using VisitType = ::VisitType;
    using Nspace = ::Nspace;
    using AsmStatement = ::AsmStatement;
    using BreakStatement = ::BreakStatement;
    using CaseRangeStatement = ::CaseRangeStatement;
    using CaseStatement = ::CaseStatement;
    using Catch = ::Catch;
    using CompoundAsmStatement = ::CompoundAsmStatement;
    using CompoundDeclarationStatement = ::CompoundDeclarationStatement;
    using CompoundStatement = ::CompoundStatement;
    using ConditionalStatement = ::ConditionalStatement;
    using ContinueStatement = ::ContinueStatement;
    using DebugStatement = ::DebugStatement;
    using DefaultStatement = ::DefaultStatement;
    using DoStatement = ::DoStatement;
    using DtorExpStatement = ::DtorExpStatement;
    using ErrorStatement = ::ErrorStatement;
    using ExpStatement = ::ExpStatement;
    using ForStatement = ::ForStatement;
    using ForeachRangeStatement = ::ForeachRangeStatement;
    using ForeachStatement = ::ForeachStatement;
    using ForwardingStatement = ::ForwardingStatement;
    using GccAsmStatement = ::GccAsmStatement;
    using GotoCaseStatement = ::GotoCaseStatement;
    using GotoDefaultStatement = ::GotoDefaultStatement;
    using GotoStatement = ::GotoStatement;
    using IfStatement = ::IfStatement;
    using ImportStatement = ::ImportStatement;
    using InlineAsmStatement = ::InlineAsmStatement;
    using LabelDsymbol = ::LabelDsymbol;
    using LabelStatement = ::LabelStatement;
    using MixinStatement = ::MixinStatement;
    using PeelStatement = ::PeelStatement;
    using PragmaStatement = ::PragmaStatement;
    using ReturnStatement = ::ReturnStatement;
    using ScopeGuardStatement = ::ScopeGuardStatement;
    using ScopeStatement = ::ScopeStatement;
    using Statement = ::Statement;
    using StaticAssertStatement = ::StaticAssertStatement;
    using StaticForeachStatement = ::StaticForeachStatement;
    using SwitchErrorStatement = ::SwitchErrorStatement;
    using SwitchStatement = ::SwitchStatement;
    using SynchronizedStatement = ::SynchronizedStatement;
    using ThrowStatement = ::ThrowStatement;
    using TryCatchStatement = ::TryCatchStatement;
    using TryFinallyStatement = ::TryFinallyStatement;
    using UnrolledLoopStatement = ::UnrolledLoopStatement;
    using VisitStatement = ::VisitStatement;
    using WhileStatement = ::WhileStatement;
    using WithStatement = ::WithStatement;
    using StaticAssert = ::StaticAssert;
    using UnionExp = ::UnionExp;
    using emplaceExp = ::emplaceExp;
    typedef UserAttributeDeclaration* UserAttributeDeclaration;
    typedef Ensure Ensure;
    typedef ErrorExp* ErrorExp;
    typedef MODFlags MODFlags;
    typedef Type* Type;
    typedef Parameter* Parameter;
    typedef ParameterList ParameterList;
    typedef VarArg VarArg;
    typedef STC STC;
    typedef Dsymbol* Dsymbol;
    typedef Array<Dsymbol* > Dsymbols;
    typedef Visibility Visibility;
    typedef SearchOpt SearchOpt;
    typedef PASS PASS;
    ASTCodegen()
    {
    }
};

class Visitor : public ParseTimeVisitor<ASTCodegen >
{
public:
    using ParseTimeVisitor<ASTCodegen >::visit;
    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(CompoundLiteralExp* 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);
    virtual void visit(LoweredAssignExp* e);
};

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

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

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

struct TargetC final
{
    enum class Runtime : uint8_t
    {
        Unspecified = 0u,
        Bionic = 1u,
        DigitalMars = 2u,
        Glibc = 3u,
        Microsoft = 4u,
        Musl = 5u,
        Newlib = 6u,
        UClibc = 7u,
        WASI = 8u,
    };

    enum class BitFieldStyle : uint8_t
    {
        Unspecified = 0u,
        DM = 1u,
        MS = 2u,
        Gcc_Clang = 3u,
    };

    bool crtDestructorsSupported;
    uint8_t boolsize;
    uint8_t shortsize;
    uint8_t intsize;
    uint8_t longsize;
    uint8_t long_longsize;
    uint8_t long_doublesize;
    uint8_t wchar_tsize;
    Runtime runtime;
    BitFieldStyle bitFieldStyle;
    TargetC() :
        crtDestructorsSupported(true),
        boolsize(),
        shortsize(),
        intsize(),
        longsize(),
        long_longsize(),
        long_doublesize(),
        wchar_tsize()
    {
    }
    TargetC(bool crtDestructorsSupported, uint8_t boolsize = 0u, uint8_t shortsize = 0u, uint8_t intsize = 0u, uint8_t longsize = 0u, uint8_t long_longsize = 0u, uint8_t long_doublesize = 0u, uint8_t wchar_tsize = 0u, Runtime runtime = (Runtime)0u, BitFieldStyle bitFieldStyle = (BitFieldStyle)0u) :
        crtDestructorsSupported(crtDestructorsSupported),
        boolsize(boolsize),
        shortsize(shortsize),
        intsize(intsize),
        longsize(longsize),
        long_longsize(long_longsize),
        long_doublesize(long_doublesize),
        wchar_tsize(wchar_tsize),
        runtime(runtime),
        bitFieldStyle(bitFieldStyle)
        {}
};

struct TargetCPP final
{
    enum class Runtime : uint8_t
    {
        Unspecified = 0u,
        Clang = 1u,
        DigitalMars = 2u,
        Gcc = 3u,
        Microsoft = 4u,
        Sun = 5u,
    };

    bool reverseOverloads;
    bool exceptions;
    bool twoDtorInVtable;
    bool splitVBasetable;
    bool wrapDtorInExternD;
    Runtime runtime;
    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(Type* t);
    bool fundamentalType(const Type* const t, bool& isFundamental);
    uint32_t derivedClassOffset(ClassDeclaration* baseClass);
    TargetCPP() :
        reverseOverloads(),
        exceptions(),
        twoDtorInVtable(),
        splitVBasetable(),
        wrapDtorInExternD()
    {
    }
    TargetCPP(bool reverseOverloads, bool exceptions = false, bool twoDtorInVtable = false, bool splitVBasetable = false, bool wrapDtorInExternD = false, Runtime runtime = (Runtime)0u) :
        reverseOverloads(reverseOverloads),
        exceptions(exceptions),
        twoDtorInVtable(twoDtorInVtable),
        splitVBasetable(splitVBasetable),
        wrapDtorInExternD(wrapDtorInExternD),
        runtime(runtime)
        {}
};

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

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

enum class ErrorKind
{
    warning = 0,
    deprecation = 1,
    error = 2,
    tip = 3,
    message = 4,
};

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

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

enum class FeatureState : uint8_t
{
    default_ = 0u,
    disabled = 1u,
    enabled = 2u,
};

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 JsonFieldFlags : uint32_t
{
    none = 0u,
    compilerInfo = 1u,
    buildInfo = 2u,
    modules = 4u,
    semantics = 8u,
};

struct CompileEnv final
{
    uint32_t versionNumber;
    _d_dynamicArray< const char > date;
    _d_dynamicArray< const char > time;
    _d_dynamicArray< const char > vendor;
    _d_dynamicArray< const char > timestamp;
    bool previewIn;
    bool ddocOutput;
    bool masm;
    CompileEnv() :
        versionNumber(),
        date(),
        time(),
        vendor(),
        timestamp(),
        previewIn(),
        ddocOutput(),
        masm()
    {
    }
    CompileEnv(uint32_t versionNumber, _d_dynamicArray< const char > date = {}, _d_dynamicArray< const char > time = {}, _d_dynamicArray< const char > vendor = {}, _d_dynamicArray< const char > timestamp = {}, bool previewIn = false, bool ddocOutput = false, bool masm = false) :
        versionNumber(versionNumber),
        date(date),
        time(time),
        vendor(vendor),
        timestamp(timestamp),
        previewIn(previewIn),
        ddocOutput(ddocOutput),
        masm(masm)
        {}
};

typedef _d_real longdouble;

typedef uint64_t uint64_t;

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;
    MangleOverride* pMangleOverride;
    Dsymbol* enclosing;
    VarDeclaration* vthis;
    VarDeclaration* vthis2;
    Array<FuncDeclaration* > invs;
    FuncDeclaration* inv;
    Dsymbol* ctor;
    CtorDeclaration* defaultCtor;
    AliasThis* aliasthis;
    Array<DtorDeclaration* > userDtors;
    DtorDeclaration* aggrDtor;
    DtorDeclaration* dtor;
    DtorDeclaration* tidtor;
    DtorDeclaration* fieldDtor;
    Expression* getRTInfo;
    Visibility visibility;
    bool noDefaultCtor;
    bool disableNew;
    Sizeok sizeok;
    virtual Scope* newScope(Scope* sc);
    virtual void finalizeSize() = 0;
    uinteger_t size(const Loc& loc) final override;
    bool fill(const Loc& loc, Array<Expression* >& elements, bool ctorinit);
    Type* getType() final override;
    bool isDeprecated() const final override;
    bool isNested() const;
    bool isExport() const final override;
    Visibility visible() final override;
    Type* handleType();
    bool hasInvariant();
    void* sinit;
    AggregateDeclaration* isAggregateDeclaration() final override;
    void accept(Visitor* v) override;
};

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

struct structalign_t final
{
private:
    uint16_t value;
    bool pack;
public:
    bool isDefault() const;
    void setDefault();
    bool isUnknown() const;
    void setUnknown();
    void set(uint32_t value);
    uint32_t get() const;
    bool isPack() const;
    void setPack(bool pack);
    structalign_t() :
        value(0u),
        pack()
    {
    }
    structalign_t(uint16_t value, bool pack = false) :
        value(value),
        pack(pack)
        {}
};

template <typename T>
struct DArray final
{
    _d_dynamicArray< T > data;
    DArray()
    {
    }
};

class AttribDeclaration : public Dsymbol
{
public:
    Array<Dsymbol* >* decl;
    virtual Array<Dsymbol* >* include(Scope* sc);
    virtual Scope* newScope(Scope* sc);
    void addComment(const char* comment) override;
    const char* kind() const override;
    bool oneMember(Dsymbol*& ps, Identifier* ident) override;
    bool hasPointers() final override;
    bool hasStaticCtorOrDtor() final override;
    void checkCtorConstInit() final override;
    void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories) final override;
    AttribDeclaration* isAttribDeclaration() override;
    void accept(Visitor* v) override;
};

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

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

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

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

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

class VisibilityDeclaration final : public AttribDeclaration
{
public:
    Visibility visibility;
    _d_dynamicArray< Identifier* > pkg_identifiers;
    VisibilityDeclaration* syntaxCopy(Dsymbol* s) override;
    Scope* newScope(Scope* sc) override;
    const char* kind() const override;
    const char* toPrettyChars(bool __param_0_) override;
    VisibilityDeclaration* isVisibilityDeclaration() override;
    void accept(Visitor* v) override;
};

class AlignDeclaration final : public AttribDeclaration
{
public:
    Array<Expression* >* exps;
    structalign_t salign;
    AlignDeclaration* syntaxCopy(Dsymbol* s) override;
    Scope* newScope(Scope* sc) override;
    void accept(Visitor* v) override;
};

class AnonDeclaration final : public AttribDeclaration
{
public:
    bool isunion;
    int32_t sem;
    uint32_t anonoffset;
    uint32_t anonstructsize;
    uint32_t anonalignsize;
    AnonDeclaration* syntaxCopy(Dsymbol* s) override;
    const char* kind() const override;
    AnonDeclaration* isAnonDeclaration() override;
    void accept(Visitor* v) override;
};

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

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

class StaticIfDeclaration final : public ConditionalDeclaration
{
public:
    ScopeDsymbol* scopesym;
private:
    bool addisdone;
    bool onStack;
public:
    StaticIfDeclaration* syntaxCopy(Dsymbol* s) override;
    Array<Dsymbol* >* include(Scope* sc) override;
    const char* kind() const override;
    StaticIfDeclaration* isStaticIfDeclaration() override;
    void accept(Visitor* v) override;
};

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

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

class MixinDeclaration final : public AttribDeclaration
{
public:
    Array<Expression* >* exps;
    ScopeDsymbol* scopesym;
    bool compiled;
    MixinDeclaration* syntaxCopy(Dsymbol* s) override;
    const char* kind() const override;
    MixinDeclaration* isMixinDeclaration() override;
    void accept(Visitor* v) override;
};

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

extern BUILTIN isBuiltin(FuncDeclaration* fd);

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

extern bool includeImports;

extern Array<const char* > includeModulePatterns;

extern Array<Module* > compiledImports;

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

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

class StaticForeach final : public RootObject
{
public:
    Loc loc;
    ForeachStatement* aggrfe;
    ForeachRangeStatement* rangefe;
    bool needExpansion;
};

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

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

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

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

extern DArray<uint8_t > preprocess(FileName csrcfile, const Loc& loc, OutBuffer& defines);

struct BaseClass final
{
    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() :
        type(),
        sym(),
        offset(),
        vtbl(),
        baseInterfaces()
    {
    }
};

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;
    bool inuse;
    ThreeState isabstract;
    Baseok baseok;
    ObjcClassDeclaration objc;
    Symbol* cpp_type_info_ptr_sym;
    static ClassDeclaration* create(const Loc& loc, Identifier* id, Array<BaseClass* >* baseclasses, Array<Dsymbol* >* members, bool inObject);
    const char* toPrettyChars(bool qualifyTypes = false) override;
    ClassDeclaration* syntaxCopy(Dsymbol* s) override;
    Scope* newScope(Scope* sc) override;
    enum : int32_t { OFFSET_RUNTIME = 1985229328 };

    enum : int32_t { OFFSET_FWDREF = 1985229329 };

    virtual bool isBaseOf(ClassDeclaration* cd, int32_t* poffset);
    bool isBaseInfoComplete() const;
    void finalizeSize() final override;
    bool hasMonitor();
    bool isFuncHidden(FuncDeclaration* fd);
    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 override;
    void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories) final override;
    Dsymbol* vtblsym;
    Dsymbol* vtblSymbol();
    ClassDeclaration* isClassDeclaration() final override;
    void accept(Visitor* v) override;
};

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

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

    enum : int32_t { ignoreRead = 2 };

    enum : int32_t { nounderscore = 4 };

    enum : int32_t { hidden = 8 };

    _d_dynamicArray< const char > mangleOverride;
    const char* kind() const override;
    uinteger_t size(const Loc& loc) final override;
    bool isStatic() const;
    LINK resolvedLinkage() const;
    virtual bool isDelete();
    virtual bool isDataseg();
    virtual bool isThreadlocal();
    virtual bool isCodeseg() const;
    bool isFinal() const;
    virtual bool isAbstract();
    bool isConst() const;
    bool isImmutable() const;
    bool isWild() const;
    bool isAuto() const;
    bool isScope() const;
    bool isReturn() const;
    bool isSynchronized() const;
    bool isParameter() const;
    bool isDeprecated() const final override;
    bool isDisabled() const;
    bool isOverride() const;
    bool isResult() const;
    bool isField() const;
    bool isIn() const;
    bool isOut() const;
    bool isRef() const;
    bool isReference() const;
    bool isFuture() const;
    Visibility visible() final override;
    Declaration* isDeclaration() final override;
    void accept(Visitor* v) override;
};

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

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

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

class VarDeclaration : public Declaration
{
public:
    Initializer* _init;
    Array<FuncDeclaration* > nestedrefs;
    TupleDeclaration* aliasTuple;
    VarDeclaration* lastVar;
    Expression* edtor;
    IntRange* range;
    Array<VarDeclaration* >* maybes;
    uint32_t endlinnum;
    uint32_t offset;
    uint32_t sequenceNumber;
    structalign_t alignment;
    enum : uint32_t { AdrOnStackNone = 4294967295u };

    uint32_t ctfeAdrOnStack;
    bool isargptr() const;
    bool isargptr(bool v);
    bool ctorinit() const;
    bool ctorinit(bool v);
    bool iscatchvar() const;
    bool iscatchvar(bool v);
    bool isowner() const;
    bool isowner(bool v);
    bool setInCtorOnly() const;
    bool setInCtorOnly(bool v);
    bool onstack() const;
    bool onstack(bool v);
    bool overlapped() const;
    bool overlapped(bool v);
    bool overlapUnsafe() const;
    bool overlapUnsafe(bool v);
    bool maybeScope() const;
    bool maybeScope(bool v);
    bool doNotInferReturn() const;
    bool doNotInferReturn(bool v);
    bool isArgDtorVar() const;
    bool isArgDtorVar(bool v);
    bool isCmacro() const;
    bool isCmacro(bool v);
    bool dllImport() const;
    bool dllImport(bool v);
    bool dllExport() const;
    bool dllExport(bool v);
    bool inClosure() const;
    bool inClosure(bool v);
    bool inAlignSection() const;
    bool inAlignSection(bool v);
    bool systemInferred() const;
    bool systemInferred(bool v);
private:
    uint32_t bitFields;
public:
    int8_t canassign;
    uint8_t isdataseg;
    static VarDeclaration* create(const Loc& loc, Type* type, Identifier* ident, Initializer* _init, StorageClass storage_class = static_cast<StorageClass>(STC::undefined_));
    VarDeclaration* syntaxCopy(Dsymbol* s) override;
    const char* kind() const override;
    AggregateDeclaration* isThis() final override;
    bool needThis() final override;
    bool isExport() const final override;
    bool isImportedSymbol() const final override;
    bool isCtorinit() const;
    bool isDataseg() final override;
    bool isThreadlocal() final override;
    bool isCTFE();
    bool isOverlappedWith(VarDeclaration* v);
    bool hasPointers() final override;
    bool canTakeAddressOf();
    bool needsScopeDtor();
    void checkCtorConstInit() final override;
    Dsymbol* toAlias() final override;
    VarDeclaration* isVarDeclaration() final override;
    void accept(Visitor* v) override;
};

class BitFieldDeclaration : public VarDeclaration
{
public:
    Expression* width;
    uint32_t fieldWidth;
    uint32_t bitOffset;
    BitFieldDeclaration* syntaxCopy(Dsymbol* s) override;
    BitFieldDeclaration* isBitFieldDeclaration() final override;
    void accept(Visitor* v) override;
    uint64_t getMinMax(Identifier* id);
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class EnumDeclaration final : public ScopeDsymbol
{
public:
    Type* type;
    Type* memtype;
    Visibility visibility;
    Expression* maxval;
    Expression* minval;
    Expression* defaultval;
    bool isdeprecated() const;
    bool isdeprecated(bool v);
    bool added() const;
    bool added(bool v);
    bool inuse() const;
    bool inuse(bool v);
private:
    uint8_t bitFields;
public:
    Symbol* sinit;
    EnumDeclaration* syntaxCopy(Dsymbol* s) override;
    bool oneMember(Dsymbol*& ps, Identifier* ident) override;
    Type* getType() override;
    const char* kind() const override;
    bool isDeprecated() const override;
    Visibility visible() override;
    bool isSpecial() const;
    EnumDeclaration* isEnumDeclaration() override;
    void accept(Visitor* v) override;
};

class EnumMember final : public VarDeclaration
{
public:
    Expression*& value();
    Expression* origValue;
    Type* origType;
    EnumDeclaration* ed;
    EnumMember* syntaxCopy(Dsymbol* s) override;
    const char* kind() const override;
    EnumMember* isEnumMember() override;
    void accept(Visitor* v) override;
};

class Import final : public Dsymbol
{
public:
    _d_dynamicArray< Identifier* > packages;
    Identifier* id;
    Identifier* aliasId;
    int32_t isstatic;
    Visibility visibility;
    Array<Identifier* > names;
    Array<Identifier* > aliases;
    Module* mod;
    Package* pkg;
    Array<AliasDeclaration* > aliasdecls;
    const char* kind() const override;
    Visibility visible() override;
    Import* syntaxCopy(Dsymbol* s) override;
    Dsymbol* toAlias() override;
    bool overloadInsert(Dsymbol* s) override;
    Import* isImport() override;
    void accept(Visitor* v) override;
};

extern void printCtfePerformanceStats();

class Package : public ScopeDsymbol
{
public:
    PKG isPkgMod;
    uint32_t tag;
    Module* mod;
    const char* kind() const override;
    bool equals(const RootObject* const o) const override;
    Package* isPackage() final override;
    bool isAncestorPackageOf(const Package* const pkg) const;
    void accept(Visitor* v) override;
    Module* isPackageMod();
    void resolvePKGunknown();
};

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 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;
    _d_dynamicArray< const uint8_t > src;
    uint32_t errors;
    uint32_t numlines;
    FileType filetype;
    bool hasAlwaysInlines;
    bool isPackageFile;
    Package* pkg;
    Array<const char* > contentImportedFiles;
    int32_t needmoduleinfo;
private:
    ThreeState selfimports;
    ThreeState rootimports;
public:
    void* tagSymTab;
private:
    OutBuffer defines;
public:
    bool selfImports();
    bool rootImports();
    Identifier* searchCacheIdent;
    Dsymbol* searchCacheSymbol;
    uint32_t searchCacheFlags;
    bool insearch;
    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 const char* find(const char* filename);
    static Module* load(const Loc& loc, Array<Identifier* >* packages, Identifier* ident);
    const char* kind() const override;
    bool read(const Loc& loc);
    Module* parse();
    int32_t needModuleInfo();
    void checkImportDeprecation(const Loc& loc, Scope* sc);
    bool isPackageAccessible(Package* p, Visibility visibility, uint32_t flags = 0u) override;
    Dsymbol* symtabInsert(Dsymbol* s) override;
    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;
    _d_dynamicArray< uint32_t > covb;
    Symbol* sictor;
    Symbol* sctor;
    Symbol* sdtor;
    Symbol* ssharedctor;
    Symbol* sshareddtor;
    Symbol* stest;
    Symbol* sfilename;
    void* ctfe_cov;
    Module* isModule() override;
    void accept(Visitor* v) override;
    void fullyQualifiedName(OutBuffer& buf);
};

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

struct Scope final
{
    Scope* enclosing;
    Module* _module;
    ScopeDsymbol* scopesym;
    FuncDeclaration* func;
    VarDeclaration* varDecl;
    Dsymbol* parent;
    LabelStatement* slabel;
    SwitchStatement* sw;
    Statement* tryBody;
    TryFinallyStatement* tf;
    ScopeGuardStatement* os;
    Statement* sbreak;
    Statement* scontinue;
    ForeachStatement* fes;
    Scope* callsc;
    Dsymbol* inunion;
    bool nofree;
    bool inLoop;
    bool inDefaultArg;
    int32_t intypeof;
    VarDeclaration* lastVar;
    ErrorSink* eSink;
    Module* minst;
    TemplateInstance* tinst;
    CtorFlow ctorflow;
    AlignDeclaration* aligndecl;
    CPPNamespaceDeclaration* namespace_;
    LINK linkage;
    CPPMANGLE cppmangle;
    PragmaDeclaration* inlining;
    Visibility visibility;
    int32_t explicitVisibility;
    StorageClass stc;
    DeprecatedDeclaration* depdecl;
    uint32_t flags;
    UserAttributeDeclaration* userAttribDecl;
    DocComment* lastdc;
    void* anchorCounts;
    Identifier* prevAnchor;
    AliasDeclaration* aliasAsg;
    Dsymbol* search(const Loc& loc, Identifier* ident, Dsymbol*& pscopesym, uint32_t flags = 0u);
    Scope() :
        enclosing(),
        _module(),
        scopesym(),
        func(),
        varDecl(),
        parent(),
        slabel(),
        sw(),
        tryBody(),
        tf(),
        os(),
        sbreak(),
        scontinue(),
        fes(),
        callsc(),
        inunion(),
        nofree(),
        inLoop(),
        inDefaultArg(),
        intypeof(),
        lastVar(),
        eSink(),
        minst(),
        tinst(),
        ctorflow(),
        aligndecl(),
        namespace_(),
        linkage((LINK)1u),
        cppmangle((CPPMANGLE)0u),
        inlining(),
        visibility(Visibility((Visibility::Kind)5u, nullptr)),
        explicitVisibility(),
        stc(),
        depdecl(),
        flags(),
        userAttribDecl(),
        lastdc(),
        prevAnchor(),
        aliasAsg()
    {
    }
    Scope(Scope* enclosing, Module* _module = nullptr, ScopeDsymbol* scopesym = nullptr, FuncDeclaration* func = nullptr, VarDeclaration* varDecl = nullptr, Dsymbol* parent = nullptr, LabelStatement* slabel = nullptr, SwitchStatement* sw = nullptr, Statement* tryBody = nullptr, TryFinallyStatement* tf = nullptr, ScopeGuardStatement* os = nullptr, Statement* sbreak = nullptr, Statement* scontinue = nullptr, ForeachStatement* fes = nullptr, Scope* callsc = nullptr, Dsymbol* inunion = nullptr, bool nofree = false, bool inLoop = false, bool inDefaultArg = false, int32_t intypeof = 0, VarDeclaration* lastVar = nullptr, ErrorSink* eSink = nullptr, Module* minst = nullptr, TemplateInstance* tinst = nullptr, CtorFlow ctorflow = CtorFlow(), AlignDeclaration* aligndecl = nullptr, CPPNamespaceDeclaration* namespace_ = nullptr, LINK linkage = (LINK)1u, CPPMANGLE cppmangle = (CPPMANGLE)0u, PragmaDeclaration* inlining = nullptr, Visibility visibility = Visibility((Visibility::Kind)5u, nullptr), int32_t explicitVisibility = 0, uint64_t stc = 0LLU, DeprecatedDeclaration* depdecl = nullptr, uint32_t flags = 0u, UserAttributeDeclaration* userAttribDecl = nullptr, DocComment* lastdc = nullptr, void* anchorCounts = nullptr, Identifier* prevAnchor = nullptr, AliasDeclaration* aliasAsg = nullptr) :
        enclosing(enclosing),
        _module(_module),
        scopesym(scopesym),
        func(func),
        varDecl(varDecl),
        parent(parent),
        slabel(slabel),
        sw(sw),
        tryBody(tryBody),
        tf(tf),
        os(os),
        sbreak(sbreak),
        scontinue(scontinue),
        fes(fes),
        callsc(callsc),
        inunion(inunion),
        nofree(nofree),
        inLoop(inLoop),
        inDefaultArg(inDefaultArg),
        intypeof(intypeof),
        lastVar(lastVar),
        eSink(eSink),
        minst(minst),
        tinst(tinst),
        ctorflow(ctorflow),
        aligndecl(aligndecl),
        namespace_(namespace_),
        linkage(linkage),
        cppmangle(cppmangle),
        inlining(inlining),
        visibility(visibility),
        explicitVisibility(explicitVisibility),
        stc(stc),
        depdecl(depdecl),
        flags(flags),
        userAttribDecl(userAttribDecl),
        lastdc(lastdc),
        anchorCounts(anchorCounts),
        prevAnchor(prevAnchor),
        aliasAsg(aliasAsg)
        {}
};

class StructDeclaration : public AggregateDeclaration
{
public:
    Array<FuncDeclaration* > postblits;
    FuncDeclaration* postblit;
    FuncDeclaration* xeq;
    FuncDeclaration* xcmp;
    FuncDeclaration* xhash;
    static FuncDeclaration* xerreq;
    static FuncDeclaration* xerrcmp;
    TypeTuple* argTypes;
    structalign_t alignment;
    ThreeState ispod;
    bool zeroInit() const;
    bool zeroInit(bool v);
    bool hasIdentityAssign() const;
    bool hasIdentityAssign(bool v);
    bool hasBlitAssign() const;
    bool hasBlitAssign(bool v);
    bool hasIdentityEquals() const;
    bool hasIdentityEquals(bool v);
    bool hasNoFields() const;
    bool hasNoFields(bool v);
    bool hasCopyCtor() const;
    bool hasCopyCtor(bool v);
    bool hasPointerField() const;
    bool hasPointerField(bool v);
    bool hasVoidInitPointers() const;
    bool hasVoidInitPointers(bool v);
    bool hasSystemFields() const;
    bool hasSystemFields(bool v);
    bool hasFieldWithInvariant() const;
    bool hasFieldWithInvariant(bool v);
    bool computedTypeProperties() const;
    bool computedTypeProperties(bool v);
    bool requestTypeInfo() const;
    bool requestTypeInfo(bool v);
private:
    uint16_t bitFields;
public:
    static StructDeclaration* create(const Loc& loc, Identifier* id, bool inObject);
    StructDeclaration* syntaxCopy(Dsymbol* s) override;
    const char* kind() const override;
    void finalizeSize() final override;
    bool isPOD();
    bool hasCopyConstruction();
    StructDeclaration* isStructDeclaration() final override;
    void accept(Visitor* v) override;
    uint32_t numArgTypes() const;
    Type* argType(uint32_t index);
    bool hasRegularCtor(bool checkDisabled = false);
};

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

class WithScopeSymbol final : public ScopeDsymbol
{
public:
    WithStatement* withstate;
    WithScopeSymbol* isWithScopeSymbol() override;
    void accept(Visitor* v) override;
};

class ArrayScopeSymbol final : public ScopeDsymbol
{
public:
    RootObject* arrayContent;
    ArrayScopeSymbol* isArrayScopeSymbol() override;
    void accept(Visitor* v) override;
};

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

class ForwardingScopeDsymbol final : public ScopeDsymbol
{
public:
    Dsymbol* symtabInsert(Dsymbol* s) override;
    Dsymbol* symtabLookup(Dsymbol* s, Identifier* id) override;
    void importScope(Dsymbol* s, Visibility visibility) override;
    const char* kind() const override;
    ForwardingScopeDsymbol* isForwardingScopeDsymbol() override;
};

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

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

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

class CAsmDeclaration final : public Dsymbol
{
public:
    Expression* code;
    CAsmDeclaration* isCAsmDeclaration() override;
    void accept(Visitor* v) override;
};

class ImportAllVisitor : public Visitor
{
public:
    using Visitor::visit;
    Scope* sc;
    ImportAllVisitor(Scope* sc);
    void visit(Dsymbol* d) override;
    void visit(Import* imp) override;
    void visit(Module* m) override;
    void visit(AttribDeclaration* atb) override;
    void visit(StaticIfDeclaration* _) override;
    void visit(StaticForeachDeclaration* _) override;
};

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

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

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

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

struct Target final
{
    enum class OS : uint8_t
    {
        none = 0u,
        linux = 1u,
        Windows = 2u,
        OSX = 4u,
        OpenBSD = 8u,
        FreeBSD = 16u,
        Solaris = 32u,
        DragonFlyBSD = 64u,
        all = 127u,
        Posix = 125u,
    };

    OS os;
    uint8_t osMajor;
    uint8_t ptrsize;
    uint8_t realsize;
    uint8_t realpad;
    uint8_t realalignsize;
    uint8_t classinfosize;
    uint64_t maxStaticDataSize;
    TargetC c;
    TargetCPP cpp;
    TargetObjC objc;
    _d_dynamicArray< const char > architectureName;
    CPU cpu;
    bool isX86_64;
    bool isLP64;
    _d_dynamicArray< const char > obj_ext;
    _d_dynamicArray< const char > lib_ext;
    _d_dynamicArray< const char > dll_ext;
    bool run_noext;
    bool omfobj;
    template <typename T>
    struct FPTypeProperties final
    {
        real_t max;
        real_t min_normal;
        real_t nan;
        real_t infinity;
        real_t epsilon;
        int64_t dig;
        int64_t mant_dig;
        int64_t max_exp;
        int64_t min_exp;
        int64_t max_10_exp;
        int64_t 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 setCPU();
    void deinitialize();
    uint32_t alignsize(Type* type);
    uint32_t fieldalign(Type* type);
    Type* va_listType(const Loc& loc, Scope* sc);
    int32_t isVectorTypeSupported(int32_t sz, Type* type);
    bool isVectorOpSupported(Type* type, EXP op, Type* t2 = nullptr);
    LINK systemLinkage();
    TypeTuple* toArgTypes(Type* t);
    bool isReturnOnStack(TypeFunction* tf, bool needsThis);
    bool preferPassByRef(Type* t);
private:
    enum class TargetInfoKeys
    {
        cppRuntimeLibrary = 0,
        cppStd = 1,
        floatAbi = 2,
        objectFormat = 3,
        CET = 4,
    };

public:
    Expression* getTargetInfo(const char* name, const Loc& loc);
    bool isCalleeDestroyingArgs(TypeFunction* tf);
    bool libraryObjectMonitors(FuncDeclaration* fd, Statement* fbody);
    bool supportsLinkerDirective() const;
    Target() :
        osMajor(),
        ptrsize(),
        realsize(),
        realpad(),
        realalignsize(),
        classinfosize(),
        maxStaticDataSize(),
        c(),
        cpp(),
        objc(),
        architectureName(),
        isX86_64(),
        isLP64(),
        obj_ext(),
        lib_ext(),
        dll_ext(),
        run_noext(),
        omfobj(),
        FloatProperties(),
        DoubleProperties(),
        RealProperties(),
        tvalist(),
        params()
    {
    }
    Target(OS os, uint8_t osMajor = 0u, uint8_t ptrsize = 0u, uint8_t realsize = 0u, uint8_t realpad = 0u, uint8_t realalignsize = 0u, uint8_t classinfosize = 0u, uint64_t maxStaticDataSize = 0LLU, TargetC c = TargetC(), TargetCPP cpp = TargetCPP(), TargetObjC objc = TargetObjC(), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)0u, bool isX86_64 = false, bool isLP64 = false, _d_dynamicArray< const char > obj_ext = {}, _d_dynamicArray< const char > lib_ext = {}, _d_dynamicArray< const char > dll_ext = {}, bool run_noext = false, bool omfobj = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(), Type* tvalist = nullptr, const Param* params = nullptr) :
        os(os),
        osMajor(osMajor),
        ptrsize(ptrsize),
        realsize(realsize),
        realpad(realpad),
        realalignsize(realalignsize),
        classinfosize(classinfosize),
        maxStaticDataSize(maxStaticDataSize),
        c(c),
        cpp(cpp),
        objc(objc),
        architectureName(architectureName),
        cpu(cpu),
        isX86_64(isX86_64),
        isLP64(isLP64),
        obj_ext(obj_ext),
        lib_ext(lib_ext),
        dll_ext(dll_ext),
        run_noext(run_noext),
        omfobj(omfobj),
        FloatProperties(FloatProperties),
        DoubleProperties(DoubleProperties),
        RealProperties(RealProperties),
        tvalist(tvalist),
        params(params)
        {}
};

extern Target target;

extern Type* getTypeInfoType(const Loc& loc, Type* t, Scope* sc, bool genObjCode = true);

class SemanticTimeTransitiveVisitor : public SemanticTimePermissiveVisitor
{
public:
    using SemanticTimePermissiveVisitor::visit;
    void visit(ExpStatement* s) override;
    void visit(MixinStatement* s) override;
    void visit(CompoundStatement* s) override;
    virtual void visitVarDecl(VarDeclaration* v);
    void visit(CompoundDeclarationStatement* s) override;
    void visit(ScopeStatement* s) override;
    void visit(WhileStatement* s) override;
    void visit(DoStatement* s) override;
    void visit(ForStatement* s) override;
    void visit(ForeachStatement* s) override;
    void visit(ForeachRangeStatement* s) override;
    void visit(StaticForeachStatement* s) override;
    void visit(IfStatement* s) override;
    void visit(ConditionalStatement* s) override;
    void visit(PragmaStatement* s) override;
    void visit(StaticAssertStatement* s) override;
    void visit(SwitchStatement* s) override;
    void visit(CaseStatement* s) override;
    void visit(CaseRangeStatement* s) override;
    void visit(DefaultStatement* s) override;
    void visit(GotoCaseStatement* s) override;
    void visit(ReturnStatement* s) override;
    void visit(SynchronizedStatement* s) override;
    void visit(WithStatement* s) override;
    void visit(TryCatchStatement* s) override;
    void visit(TryFinallyStatement* s) override;
    void visit(ScopeGuardStatement* s) override;
    void visit(ThrowStatement* s) override;
    void visit(LabelStatement* s) override;
    void visit(ImportStatement* s) override;
    virtual void visit(Catch* c);
    virtual void visitType(Type* t);
    virtual void visitFunctionType(TypeFunction* t, TemplateDeclaration* td);
    void visit(TypeVector* t) override;
    void visit(TypeSArray* t) override;
    void visit(TypeDArray* t) override;
    void visit(TypeAArray* t) override;
    void visit(TypePointer* t) override;
    void visit(TypeReference* t) override;
    void visit(TypeFunction* t) override;
    void visit(TypeDelegate* t) override;
    virtual void visitTypeQualified(TypeQualified* t);
    void visit(TypeIdentifier* t) override;
    void visit(TypeInstance* t) override;
    void visit(TypeTypeof* t) override;
    void visit(TypeReturn* t) override;
    void visit(TypeTuple* t) override;
    void visit(TypeSlice* t) override;
    void visit(TypeTraits* t) override;
    void visit(TypeMixin* t) override;
    void visit(StaticAssert* s) override;
    void visit(EnumMember* em) override;
    virtual void visitAttribDeclaration(AttribDeclaration* d);
    void visit(AttribDeclaration* d) override;
    void visit(StorageClassDeclaration* d) override;
    void visit(DeprecatedDeclaration* d) override;
    void visit(LinkDeclaration* d) override;
    void visit(CPPMangleDeclaration* d) override;
    void visit(VisibilityDeclaration* d) override;
    void visit(AlignDeclaration* d) override;
    void visit(AnonDeclaration* d) override;
    void visit(PragmaDeclaration* d) override;
    void visit(ConditionalDeclaration* d) override;
    void visit(MixinDeclaration* d) override;
    void visit(UserAttributeDeclaration* d) override;
    virtual void visitFuncBody(FuncDeclaration* f);
    virtual void visitBaseClasses(ClassDeclaration* d);
    virtual bool visitEponymousMember(TemplateDeclaration* d);
    virtual void visitTemplateParameters(Array<TemplateParameter* >* parameters);
    void visit(TemplateDeclaration* d) override;
    virtual void visitObject(RootObject* oarg);
    virtual void visitTiargs(TemplateInstance* ti);
    void visit(TemplateInstance* ti) override;
    void visit(TemplateMixin* tm) override;
    void visit(EnumDeclaration* d) override;
    void visit(Nspace* d) override;
    void visit(StructDeclaration* d) override;
    void visit(UnionDeclaration* d) override;
    void visit(ClassDeclaration* d) override;
    void visit(InterfaceDeclaration* d) override;
    void visit(AliasDeclaration* d) override;
    void visit(AliasAssign* d) override;
    void visit(VarDeclaration* d) override;
    void visit(FuncDeclaration* f) override;
    void visit(FuncLiteralDeclaration* f) override;
    void visit(PostBlitDeclaration* d) override;
    void visit(DtorDeclaration* d) override;
    void visit(CtorDeclaration* d) override;
    void visit(StaticCtorDeclaration* d) override;
    void visit(StaticDtorDeclaration* d) override;
    void visit(InvariantDeclaration* d) override;
    void visit(UnitTestDeclaration* d) override;
    void visit(NewDeclaration* d) override;
    void visit(StructInitializer* si) override;
    void visit(ArrayInitializer* ai) override;
    void visit(ExpInitializer* ei) override;
    void visit(CInitializer* ci) override;
    void visit(ArrayLiteralExp* e) override;
    void visit(AssocArrayLiteralExp* e) override;
    void visit(TypeExp* e) override;
    void visit(ScopeExp* e) override;
    void visit(NewExp* e) override;
    void visit(NewAnonClassExp* e) override;
    void visit(TupleExp* e) override;
    void visit(FuncExp* e) override;
    void visit(DeclarationExp* e) override;
    void visit(TypeidExp* e) override;
    void visit(TraitsExp* e) override;
    void visit(IsExp* e) override;
    void visit(UnaExp* e) override;
    void visit(BinExp* e) override;
    void visit(MixinExp* e) override;
    void visit(ImportExp* e) override;
    void visit(AssertExp* e) override;
    void visit(DotIdExp* e) override;
    void visit(DotTemplateInstanceExp* e) override;
    void visit(CallExp* e) override;
    void visit(PtrExp* e) override;
    void visit(DeleteExp* e) override;
    void visit(CastExp* e) override;
    void visit(IntervalExp* e) override;
    void visit(ArrayExp* e) override;
    void visit(PostExp* e) override;
    void visit(CondExp* e) override;
    void visit(GenericExp* e) override;
    void visit(ThrowExp* e) override;
    void visit(TemplateTypeParameter* tp) override;
    void visit(TemplateThisParameter* tp) override;
    void visit(TemplateAliasParameter* tp) override;
    void visit(TemplateValueParameter* tp) override;
    void visit(StaticIfCondition* c) override;
    void visit(Parameter* p) override;
    void visit(Module* m) override;
    void visit(PeelStatement* s) override;
    void visit(UnrolledLoopStatement* s) override;
    void visit(DebugStatement* s) override;
    void visit(ForwardingStatement* s) override;
    void visit(StructLiteralExp* e) override;
    void visit(CompoundLiteralExp* e) override;
    void visit(DotTemplateExp* e) override;
    void visit(DotVarExp* e) override;
    void visit(DelegateExp* e) override;
    void visit(DotTypeExp* e) override;
    void visit(VectorExp* e) override;
    void visit(VectorArrayExp* e) override;
    void visit(SliceExp* e) override;
    void visit(ArrayLengthExp* e) override;
    void visit(DelegatePtrExp* e) override;
    void visit(DelegateFuncptrExp* e) override;
    void visit(DotExp* e) override;
    void visit(IndexExp* e) override;
    void visit(RemoveExp* e) override;
    void visit(LoweredAssignExp* e) override;
};

extern _d_real creall(complex_t x);

extern _d_real cimagl(complex_t x);

extern void browse(const char* url);

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 verrorReport(const Loc& loc, const char* format, va_list ap, ErrorKind kind, const char* p1 = nullptr, const char* p2 = nullptr);

extern void verrorReportSupplemental(const Loc& loc, const char* format, va_list ap, ErrorKind kind);

extern void fatal();

extern void halt();

struct Output final
{
    bool doOutput;
    bool fullOutput;
    _d_dynamicArray< const char > dir;
    _d_dynamicArray< const char > name;
    Array<const char* > files;
    OutBuffer* buffer;
    int32_t bufferLines;
    Output() :
        doOutput(),
        fullOutput(),
        dir(),
        name(),
        files(),
        buffer(),
        bufferLines()
    {
    }
    Output(bool doOutput, bool fullOutput = false, _d_dynamicArray< const char > dir = {}, _d_dynamicArray< const char > name = {}, Array<const char* > files = Array<const char* >(), OutBuffer* buffer = nullptr, int32_t bufferLines = 0) :
        doOutput(doOutput),
        fullOutput(fullOutput),
        dir(dir),
        name(name),
        files(files),
        buffer(buffer),
        bufferLines(bufferLines)
        {}
};

struct Help final
{
    bool manual;
    bool usage;
    bool mcpu;
    bool transition;
    bool check;
    bool checkAction;
    bool revert;
    bool preview;
    bool externStd;
    bool hc;
    Help() :
        manual(),
        usage(),
        mcpu(),
        transition(),
        check(),
        checkAction(),
        revert(),
        preview(),
        externStd(),
        hc()
    {
    }
    Help(bool manual, bool usage = false, bool mcpu = false, bool transition = false, bool check = false, bool checkAction = false, bool revert = false, bool preview = false, bool externStd = false, bool hc = false) :
        manual(manual),
        usage(usage),
        mcpu(mcpu),
        transition(transition),
        check(check),
        checkAction(checkAction),
        revert(revert),
        preview(preview),
        externStd(externStd),
        hc(hc)
        {}
};

struct Verbose final
{
    bool verbose;
    bool showColumns;
    bool tls;
    bool templates;
    bool templatesListInstances;
    bool gc;
    bool field;
    bool complex;
    bool vin;
    bool showGaggedErrors;
    bool printErrorContext;
    bool logo;
    bool color;
    bool cov;
    MessageStyle messageStyle;
    uint32_t errorLimit;
    uint32_t errorSupplementLimit;
    uint32_t errorSupplementCount();
    Verbose() :
        verbose(),
        showColumns(),
        tls(),
        templates(),
        templatesListInstances(),
        gc(),
        field(),
        complex(true),
        vin(),
        showGaggedErrors(),
        printErrorContext(),
        logo(),
        color(),
        cov(),
        messageStyle((MessageStyle)0u),
        errorLimit(20u),
        errorSupplementLimit(6u)
    {
    }
    Verbose(bool verbose, bool showColumns = false, bool tls = false, bool templates = false, bool templatesListInstances = false, bool gc = false, bool field = false, bool complex = true, bool vin = false, bool showGaggedErrors = false, bool printErrorContext = false, bool logo = false, bool color = false, bool cov = false, MessageStyle messageStyle = (MessageStyle)0u, uint32_t errorLimit = 20u, uint32_t errorSupplementLimit = 6u) :
        verbose(verbose),
        showColumns(showColumns),
        tls(tls),
        templates(templates),
        templatesListInstances(templatesListInstances),
        gc(gc),
        field(field),
        complex(complex),
        vin(vin),
        showGaggedErrors(showGaggedErrors),
        printErrorContext(printErrorContext),
        logo(logo),
        color(color),
        cov(cov),
        messageStyle(messageStyle),
        errorLimit(errorLimit),
        errorSupplementLimit(errorSupplementLimit)
        {}
};

struct Param final
{
    bool obj;
    bool multiobj;
    bool trace;
    bool tracegc;
    bool vcg_ast;
    DiagnosticReporting useDeprecated;
    bool useUnitTests;
    bool useInline;
    bool release;
    bool preservePaths;
    DiagnosticReporting warnings;
    bool cov;
    uint8_t covPercent;
    bool ctfe_cov;
    bool ignoreUnsupportedPragmas;
    bool useModuleInfo;
    bool useTypeInfo;
    bool useExceptions;
    bool useGC;
    bool betterC;
    bool addMain;
    bool allInst;
    bool bitfields;
    CppStdRevision cplusplus;
    Help help;
    Verbose v;
    FeatureState useDIP25;
    FeatureState useDIP1000;
    bool ehnogc;
    bool useDIP1021;
    FeatureState fieldwise;
    bool fixAliasThis;
    FeatureState rvalueRefParam;
    FeatureState noSharedAccess;
    bool previewIn;
    bool inclusiveInContracts;
    bool shortenedMethods;
    bool fixImmutableConv;
    bool fix16997;
    FeatureState dtorFields;
    FeatureState systemVariables;
    CHECKENABLE useInvariants;
    CHECKENABLE useIn;
    CHECKENABLE useOut;
    CHECKENABLE useArrayBounds;
    CHECKENABLE useAssert;
    CHECKENABLE useSwitchError;
    CHECKENABLE boundscheck;
    CHECKACTION checkAction;
    _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;
    Output ddoc;
    Output dihdr;
    Output cxxhdr;
    Output json;
    JsonFieldFlags jsonFieldFlags;
    Output makeDeps;
    Output mixinOut;
    Output moduleDeps;
    uint32_t debuglevel;
    uint32_t versionlevel;
    bool run;
    Array<const char* > runargs;
    Array<const char* > cppswitches;
    const char* cpp;
    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;
    bool parsingUnittestsRequired();
    Param() :
        obj(true),
        multiobj(),
        trace(),
        tracegc(),
        vcg_ast(),
        useDeprecated((DiagnosticReporting)1u),
        useUnitTests(),
        useInline(false),
        release(),
        preservePaths(),
        warnings((DiagnosticReporting)2u),
        cov(),
        covPercent(),
        ctfe_cov(false),
        ignoreUnsupportedPragmas(true),
        useModuleInfo(true),
        useTypeInfo(true),
        useExceptions(true),
        useGC(true),
        betterC(),
        addMain(),
        allInst(),
        bitfields(),
        cplusplus((CppStdRevision)201103u),
        help(),
        v(),
        useDIP25((FeatureState)2u),
        ehnogc(),
        useDIP1021(),
        fixAliasThis(),
        previewIn(),
        inclusiveInContracts(),
        shortenedMethods(true),
        fixImmutableConv(),
        fix16997(true),
        useInvariants((CHECKENABLE)0u),
        useIn((CHECKENABLE)0u),
        useOut((CHECKENABLE)0u),
        useArrayBounds((CHECKENABLE)0u),
        useAssert((CHECKENABLE)0u),
        useSwitchError((CHECKENABLE)0u),
        boundscheck((CHECKENABLE)0u),
        checkAction((CHECKACTION)0u),
        argv0(),
        modFileAliasStrings(),
        imppath(),
        fileImppath(),
        objdir(),
        objname(),
        libname(),
        ddoc(),
        dihdr(),
        cxxhdr(),
        json(),
        makeDeps(),
        mixinOut(),
        moduleDeps(),
        debuglevel(),
        versionlevel(),
        run(),
        runargs(),
        cppswitches(),
        cpp(),
        objfiles(),
        linkswitches(),
        linkswitchIsForCC(),
        libfiles(),
        dllfiles(),
        deffile(),
        resfile(),
        exefile(),
        mapfile()
    {
    }
    Param(bool obj, bool multiobj = false, bool trace = false, bool tracegc = false, bool vcg_ast = false, DiagnosticReporting useDeprecated = (DiagnosticReporting)1u, bool useUnitTests = false, bool useInline = false, bool release = false, bool preservePaths = false, DiagnosticReporting warnings = (DiagnosticReporting)2u, bool cov = false, uint8_t covPercent = 0u, bool ctfe_cov = false, bool ignoreUnsupportedPragmas = true, bool useModuleInfo = true, bool useTypeInfo = true, bool useExceptions = true, bool useGC = true, bool betterC = false, bool addMain = false, bool allInst = false, bool bitfields = false, CppStdRevision cplusplus = (CppStdRevision)201103u, Help help = Help(), Verbose v = Verbose(), FeatureState useDIP25 = (FeatureState)2u, FeatureState useDIP1000 = (FeatureState)0u, bool ehnogc = false, bool useDIP1021 = false, FeatureState fieldwise = (FeatureState)0u, bool fixAliasThis = false, FeatureState rvalueRefParam = (FeatureState)0u, FeatureState noSharedAccess = (FeatureState)0u, bool previewIn = false, bool inclusiveInContracts = false, bool shortenedMethods = true, bool fixImmutableConv = false, bool fix16997 = true, FeatureState dtorFields = (FeatureState)0u, FeatureState systemVariables = (FeatureState)0u, CHECKENABLE useInvariants = (CHECKENABLE)0u, CHECKENABLE useIn = (CHECKENABLE)0u, CHECKENABLE useOut = (CHECKENABLE)0u, CHECKENABLE useArrayBounds = (CHECKENABLE)0u, CHECKENABLE useAssert = (CHECKENABLE)0u, CHECKENABLE useSwitchError = (CHECKENABLE)0u, CHECKENABLE boundscheck = (CHECKENABLE)0u, CHECKACTION checkAction = (CHECKACTION)0u, _d_dynamicArray< const char > argv0 = {}, Array<const char* > modFileAliasStrings = Array<const char* >(), Array<const char* > imppath = Array<const char* >(), Array<const char* > fileImppath = Array<const char* >(), _d_dynamicArray< const char > objdir = {}, _d_dynamicArray< const char > objname = {}, _d_dynamicArray< const char > libname = {}, Output ddoc = Output(), Output dihdr = Output(), Output cxxhdr = Output(), Output json = Output(), JsonFieldFlags jsonFieldFlags = (JsonFieldFlags)0u, Output makeDeps = Output(), Output mixinOut = Output(), Output moduleDeps = Output(), uint32_t debuglevel = 0u, uint32_t versionlevel = 0u, bool run = false, Array<const char* > runargs = Array<const char* >(), Array<const char* > cppswitches = Array<const char* >(), const char* cpp = nullptr, Array<const char* > objfiles = Array<const char* >(), Array<const char* > linkswitches = Array<const char* >(), Array<bool > linkswitchIsForCC = Array<bool >(), Array<const char* > libfiles = Array<const char* >(), Array<const char* > dllfiles = Array<const char* >(), _d_dynamicArray< const char > deffile = {}, _d_dynamicArray< const char > resfile = {}, _d_dynamicArray< const char > exefile = {}, _d_dynamicArray< const char > mapfile = {}) :
        obj(obj),
        multiobj(multiobj),
        trace(trace),
        tracegc(tracegc),
        vcg_ast(vcg_ast),
        useDeprecated(useDeprecated),
        useUnitTests(useUnitTests),
        useInline(useInline),
        release(release),
        preservePaths(preservePaths),
        warnings(warnings),
        cov(cov),
        covPercent(covPercent),
        ctfe_cov(ctfe_cov),
        ignoreUnsupportedPragmas(ignoreUnsupportedPragmas),
        useModuleInfo(useModuleInfo),
        useTypeInfo(useTypeInfo),
        useExceptions(useExceptions),
        useGC(useGC),
        betterC(betterC),
        addMain(addMain),
        allInst(allInst),
        bitfields(bitfields),
        cplusplus(cplusplus),
        help(help),
        v(v),
        useDIP25(useDIP25),
        useDIP1000(useDIP1000),
        ehnogc(ehnogc),
        useDIP1021(useDIP1021),
        fieldwise(fieldwise),
        fixAliasThis(fixAliasThis),
        rvalueRefParam(rvalueRefParam),
        noSharedAccess(noSharedAccess),
        previewIn(previewIn),
        inclusiveInContracts(inclusiveInContracts),
        shortenedMethods(shortenedMethods),
        fixImmutableConv(fixImmutableConv),
        fix16997(fix16997),
        dtorFields(dtorFields),
        systemVariables(systemVariables),
        useInvariants(useInvariants),
        useIn(useIn),
        useOut(useOut),
        useArrayBounds(useArrayBounds),
        useAssert(useAssert),
        useSwitchError(useSwitchError),
        boundscheck(boundscheck),
        checkAction(checkAction),
        argv0(argv0),
        modFileAliasStrings(modFileAliasStrings),
        imppath(imppath),
        fileImppath(fileImppath),
        objdir(objdir),
        objname(objname),
        libname(libname),
        ddoc(ddoc),
        dihdr(dihdr),
        cxxhdr(cxxhdr),
        json(json),
        jsonFieldFlags(jsonFieldFlags),
        makeDeps(makeDeps),
        mixinOut(mixinOut),
        moduleDeps(moduleDeps),
        debuglevel(debuglevel),
        versionlevel(versionlevel),
        run(run),
        runargs(runargs),
        cppswitches(cppswitches),
        cpp(cpp),
        objfiles(objfiles),
        linkswitches(linkswitches),
        linkswitchIsForCC(linkswitchIsForCC),
        libfiles(libfiles),
        dllfiles(dllfiles),
        deffile(deffile),
        resfile(resfile),
        exefile(exefile),
        mapfile(mapfile)
        {}
};

struct Global final
{
    _d_dynamicArray< const char > inifilename;
    _d_dynamicArray< const char > copyright;
    _d_dynamicArray< const char > written;
    Array<const char* > path;
    Array<const char* > filePath;
    char datetime[26LLU];
    CompileEnv compileEnv;
    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;
    bool hasMainFunction;
    uint32_t varSequenceNumber;
    FileManager* fileManager;
    enum : int32_t { recursionLimit = 500 };

    ErrorSink* errorSink;
    ErrorSink* errorSinkNull;
    DArray<uint8_t >(*preprocess)(FileName , const Loc& , OutBuffer& );
    uint32_t startGagging();
    bool endGagging(uint32_t oldGagged);
    void increaseErrorCount();
    void _init();
    uint32_t versionNumber();
    const char* const versionChars();
    Global() :
        inifilename(),
        copyright(73, "Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved"),
        written(24, "written by Walter Bright"),
        path(),
        filePath(),
        compileEnv(),
        params(),
        errors(),
        warnings(),
        gag(),
        gaggedErrors(),
        gaggedWarnings(),
        console(),
        versionids(),
        debugids(),
        hasMainFunction(),
        varSequenceNumber(1u),
        fileManager(),
        errorSink(),
        errorSinkNull(),
        preprocess()
    {
    }
    Global(_d_dynamicArray< const char > inifilename, _d_dynamicArray< const char > copyright = { 73, "Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved" }, _d_dynamicArray< const char > written = { 24, "written by Walter Bright" }, Array<const char* > path = Array<const char* >(), Array<const char* > filePath = Array<const char* >(), CompileEnv compileEnv = CompileEnv(), Param params = Param(), uint32_t errors = 0u, uint32_t warnings = 0u, uint32_t gag = 0u, uint32_t gaggedErrors = 0u, uint32_t gaggedWarnings = 0u, void* console = nullptr, Array<Identifier* > versionids = Array<Identifier* >(), Array<Identifier* > debugids = Array<Identifier* >(), bool hasMainFunction = false, uint32_t varSequenceNumber = 1u, FileManager* fileManager = nullptr, ErrorSink* errorSink = nullptr, ErrorSink* errorSinkNull = nullptr, DArray<uint8_t >(*preprocess)(FileName , const Loc& , OutBuffer& ) = nullptr) :
        inifilename(inifilename),
        copyright(copyright),
        written(written),
        path(path),
        filePath(filePath),
        compileEnv(compileEnv),
        params(params),
        errors(errors),
        warnings(warnings),
        gag(gag),
        gaggedErrors(gaggedErrors),
        gaggedWarnings(gaggedWarnings),
        console(console),
        versionids(versionids),
        debugids(debugids),
        hasMainFunction(hasMainFunction),
        varSequenceNumber(varSequenceNumber),
        fileManager(fileManager),
        errorSink(errorSink),
        errorSinkNull(errorSinkNull),
        preprocess(preprocess)
        {}
};

extern Global global;

struct Id final
{
    static Identifier* IUnknown;
    static Identifier* Object;
    static Identifier* object;
    static Identifier* _size_t;
    static Identifier* _ptrdiff_t;
    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* cppdtor;
    static Identifier* ticppdtor;
    static Identifier* postblit;
    static Identifier* classInvariant;
    static Identifier* unitTest;
    static Identifier* require;
    static Identifier* ensure;
    static Identifier* capture;
    static Identifier* this2;
    static Identifier* _init;
    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* 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* dotdotdot;
    static Identifier* p;
    static Identifier* gate;
    static Identifier* cpp_type_info_ptr;
    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* _dollar;
    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* _aaAsStruct;
    static Identifier* monitorenter;
    static Identifier* monitorexit;
    static Identifier* criticalenter;
    static Identifier* criticalexit;
    static Identifier* _d_delThrowable;
    static Identifier* _d_newThrowable;
    static Identifier* _d_newclassT;
    static Identifier* _d_newclassTTrace;
    static Identifier* _d_newitemT;
    static Identifier* _d_newitemTTrace;
    static Identifier* _d_newarrayT;
    static Identifier* _d_newarrayTTrace;
    static Identifier* _d_newarraymTX;
    static Identifier* _d_newarraymTXTrace;
    static Identifier* _d_assert_fail;
    static Identifier* dup;
    static Identifier* _aaApply;
    static Identifier* _aaApply2;
    static Identifier* _d_arrayctor;
    static Identifier* _d_arraysetctor;
    static Identifier* _d_arraysetassign;
    static Identifier* _d_arrayassign_l;
    static Identifier* _d_arrayassign_r;
    static Identifier* imported;
    static Identifier* InterpolationHeader;
    static Identifier* InterpolationFooter;
    static Identifier* InterpolatedLiteral;
    static Identifier* InterpolatedExpression;
    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* main;
    static Identifier* WinMain;
    static Identifier* DllMain;
    static Identifier* CMain;
    static Identifier* rt_init;
    static Identifier* _d_HookTraceImpl;
    static Identifier* _d_arraysetlengthTImpl;
    static Identifier* _d_arraysetlengthT;
    static Identifier* _d_arraysetlengthTTrace;
    static Identifier* _d_arrayappendT;
    static Identifier* _d_arrayappendTTrace;
    static Identifier* _d_arrayappendcTX;
    static Identifier* _d_arrayappendcTXTrace;
    static Identifier* _d_arraycatnTX;
    static Identifier* _d_arraycatnTXTrace;
    static Identifier* stdc;
    static Identifier* stdarg;
    static Identifier* va_start;
    static Identifier* std;
    static Identifier* core;
    static Identifier* config;
    static Identifier* c_complex_float;
    static Identifier* c_complex_double;
    static Identifier* c_complex_real;
    static Identifier* etc;
    static Identifier* attribute;
    static Identifier* atomic;
    static Identifier* atomicOp;
    static Identifier* math;
    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* bitop;
    static Identifier* bsf;
    static Identifier* bsr;
    static Identifier* btc;
    static Identifier* btr;
    static Identifier* bts;
    static Identifier* bswap;
    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* fullyQualifiedName;
    static Identifier* getProtection;
    static Identifier* getVisibility;
    static Identifier* parent;
    static Identifier* child;
    static Identifier* getMember;
    static Identifier* getOverloads;
    static Identifier* getVirtualFunctions;
    static Identifier* getVirtualMethods;
    static Identifier* classInstanceSize;
    static Identifier* classInstanceAlignment;
    static Identifier* allMembers;
    static Identifier* derivedMembers;
    static Identifier* isSame;
    static Identifier* compiles;
    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* initSymbol;
    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* toType;
    static Identifier* parameters;
    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* udaMustUse;
    static Identifier* udaStandalone;
    static Identifier* TRUE;
    static Identifier* FALSE;
    static Identifier* ImportC;
    static Identifier* dllimport;
    static Identifier* dllexport;
    static Identifier* naked;
    static Identifier* thread;
    static Identifier* vector_size;
    static Identifier* always_inline;
    static Identifier* noinline;
    static Identifier* noreturn;
    static Identifier* _nothrow;
    static Identifier* _deprecated;
    static Identifier* _align;
    static Identifier* aligned;
    static Identifier* builtins;
    static Identifier* builtin_va_list;
    static Identifier* builtin_va_arg;
    static Identifier* va_list_tag;
    static Identifier* va_arg;
    static Identifier* pack;
    static Identifier* show;
    static Identifier* push;
    static Identifier* pop;
    static Identifier* _pure;
    static Identifier* define;
    static Identifier* undef;
    static Identifier* ident;
    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 override;
    int32_t getValue() const;
    bool isAnonymous() const;
    const char* toHChars2() const;
    DYNCAST dyncast() const override;
    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 final
{
    Token* next;
    Loc loc;
    const char* ptr;
    TOK value;
    _d_dynamicArray< const char > blockComment;
    _d_dynamicArray< const char > lineComment;
    union
    {
        int64_t intvalue;
        uint64_t unsvalue;
        _d_real floatvalue;
        struct
        {
            union
            {
                const char* ustring;
                InterpolatedSet* interpolatedSet;
            };
            uint32_t len;
            uint8_t postfix;
        };
        Identifier* ident;
    };
    void setString(const char* ptr, size_t length);
    void setString(const OutBuffer& buf);
    void setString();
    const char* toChars() const;
    static const char* toChars(TOK value);
    Token() :
        next(),
        loc(),
        ptr(),
        blockComment(),
        lineComment()
    {
    }
    Token(Token* next, Loc loc = Loc(), const char* ptr = nullptr, TOK value = (TOK)0u, _d_dynamicArray< const char > blockComment = {}, _d_dynamicArray< const char > lineComment = {}) :
        next(next),
        loc(loc),
        ptr(ptr),
        value(value),
        blockComment(blockComment),
        lineComment(lineComment)
        {}
};

using real_t = longdouble;

struct CTFloat final
{
    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);
    static int32_t sprint(char* str, size_t size, 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()
    {
    }
};

struct Port final
{
    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 final
{
    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);
