// Automatically generated by Digital Mars D Compiler

#pragma once

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

#ifdef CUSTOM_D_ARRAY_TYPE
#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
#else
/// Represents a D [] array
template<typename T>
struct _d_dynamicArray 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;
class CPPNamespaceDeclaration;
struct Symbol;
struct OutBuffer;
class FileManager;
struct Scope;
class DeprecatedDeclaration;
class UserAttributeDeclaration;
class Module;
class TemplateInstance;
class ScopeDsymbol;
class AggregateDeclaration;
class LabelDsymbol;
class ClassDeclaration;
class Type;
class Package;
struct FieldState;
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 ForwardingScopeDsymbol;
class WithScopeSymbol;
class ArrayScopeSymbol;
class Import;
class EnumDeclaration;
class SymbolDeclaration;
class AttribDeclaration;
class AnonDeclaration;
class VisibilityDeclaration;
class OverloadSet;
class CompileDeclaration;
class StaticAssert;
class DsymbolTable;
struct MangleOverride;
class AliasThis;
class Expression;
class TypeTuple;
class Condition;
class StaticForeach;
struct UnionExp;
class DebugCondition;
class VersionCondition;
class ForeachStatement;
class ForeachRangeStatement;
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 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 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;
class TypeInfoClassDeclaration;
class TypeFunction;
class Initializer;
struct IntRange;
struct ModuleDeclaration;
struct Escape;
class WithStatement;
struct AA;
class Tuple;
class Parameter;
class TemplateParameter;
struct TemplatePrevious;
class TemplateTupleParameter;
struct TYPE;
class TypeBasic;
class TypeError;
class TypeVector;
class TypeSArray;
class TypeDArray;
class TypeAArray;
class TypePointer;
class TypeReference;
class TypeDelegate;
class TypeIdentifier;
class TypeInstance;
class TypeTypeof;
class TypeReturn;
class TypeStruct;
class TypeEnum;
class TypeClass;
class TypeSlice;
class TypeNull;
class TypeMixin;
class TypeTraits;
class TypeNoreturn;
class TypeTag;
class TemplateTypeParameter;
class TemplateValueParameter;
class TemplateAliasParameter;
class TemplateThisParameter;
class TypeQualified;
class CaseStatement;
class Catch;
struct Designator;
class Statement;
class GotoCaseStatement;
class GotoStatement;
class ReturnStatement;
class ScopeStatement;
struct ObjcSelector;
class PeelStatement;
class CompoundStatement;
class CompoundDeclarationStatement;
class UnrolledLoopStatement;
class WhileStatement;
class DoStatement;
class ForStatement;
class IfStatement;
class SwitchStatement;
class CaseRangeStatement;
class DefaultStatement;
class SynchronizedStatement;
class TryCatchStatement;
class TryFinallyStatement;
class DebugStatement;
class LabelStatement;
class ErrorInitializer;
class VoidInitializer;
class StructInitializer;
class ArrayInitializer;
class ExpInitializer;
class CInitializer;
class ErrorStatement;
class ExpStatement;
class ConditionalStatement;
class StaticForeachStatement;
class GotoDefaultStatement;
class BreakStatement;
class DtorExpStatement;
class CompileStatement;
class ForwardingStatement;
class ContinueStatement;
class ThrowStatement;
class ScopeGuardStatement;
class SwitchErrorStatement;
struct Token;
struct code;
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 DiagnosticReporting : uint8_t
{
    error = 0u,
    inform = 1u,
    off = 2u,
};

enum class FeatureState : int8_t
{
    default_ = -1,
    disabled = 0,
    enabled = 1,
};

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

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

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

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

typedef uint64_t size_t;

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 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 CxxHeaderMode : uint32_t
{
    none = 0u,
    silent = 1u,
    verbose = 2u,
};

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

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

struct Param final
{
    bool obj;
    bool link;
    bool dll;
    bool lib;
    bool multiobj;
    bool oneobj;
    bool trace;
    bool tracegc;
    bool verbose;
    bool vcg_ast;
    bool showColumns;
    bool vtls;
    bool vtemplates;
    bool vtemplatesListInstances;
    bool vgc;
    bool vfield;
    bool vcomplex;
    bool vin;
    uint8_t symdebug;
    bool symdebugref;
    bool optimize;
    DiagnosticReporting useDeprecated;
    bool stackstomp;
    bool useUnitTests;
    bool useInline;
    FeatureState useDIP25;
    FeatureState useDIP1000;
    bool useDIP1021;
    bool release;
    bool preservePaths;
    DiagnosticReporting warnings;
    PIC pic;
    bool color;
    bool cov;
    uint8_t covPercent;
    bool ctfe_cov;
    bool nofloat;
    bool ignoreUnsupportedPragmas;
    bool useModuleInfo;
    bool useTypeInfo;
    bool useExceptions;
    bool noSharedAccess;
    bool previewIn;
    bool shortenedMethods;
    bool betterC;
    bool addMain;
    bool allInst;
    bool fix16997;
    bool fixAliasThis;
    bool inclusiveInContracts;
    bool ehnogc;
    FeatureState dtorFields;
    bool fieldwise;
    FeatureState rvalueRefParam;
    CppStdRevision cplusplus;
    bool markdown;
    bool vmarkdown;
    bool showGaggedErrors;
    bool printErrorContext;
    bool manual;
    bool usage;
    bool mcpuUsage;
    bool transitionUsage;
    bool checkUsage;
    bool checkActionUsage;
    bool revertUsage;
    bool previewUsage;
    bool externStdUsage;
    bool hcUsage;
    bool logo;
    CHECKENABLE useInvariants;
    CHECKENABLE useIn;
    CHECKENABLE useOut;
    CHECKENABLE useArrayBounds;
    CHECKENABLE useAssert;
    CHECKENABLE useSwitchError;
    CHECKENABLE boundscheck;
    CHECKACTION checkAction;
    uint32_t errorLimit;
    _d_dynamicArray< const char > argv0;
    Array<const char* > modFileAliasStrings;
    Array<const char* >* imppath;
    Array<const char* >* fileImppath;
    _d_dynamicArray< const char > objdir;
    _d_dynamicArray< const char > objname;
    _d_dynamicArray< const char > libname;
    bool doDocComments;
    _d_dynamicArray< const char > docdir;
    _d_dynamicArray< const char > docname;
    Array<const char* > ddocfiles;
    bool doHdrGeneration;
    _d_dynamicArray< const char > hdrdir;
    _d_dynamicArray< const char > hdrname;
    bool hdrStripPlainFunctions;
    CxxHeaderMode doCxxHdrGeneration;
    _d_dynamicArray< const char > cxxhdrdir;
    _d_dynamicArray< const char > cxxhdrname;
    bool doJsonGeneration;
    _d_dynamicArray< const char > jsonfilename;
    JsonFieldFlags jsonFieldFlags;
    OutBuffer* mixinOut;
    const char* mixinFile;
    int32_t mixinLines;
    uint32_t debuglevel;
    Array<const char* >* debugids;
    uint32_t versionlevel;
    Array<const char* >* versionids;
    _d_dynamicArray< const char > defaultlibname;
    _d_dynamicArray< const char > debuglibname;
    _d_dynamicArray< const char > mscrtlib;
    _d_dynamicArray< const char > moduleDepsFile;
    OutBuffer* moduleDeps;
    bool emitMakeDeps;
    _d_dynamicArray< const char > makeDepsFile;
    Array<const char* > makeDeps;
    MessageStyle messageStyle;
    bool run;
    Array<const char* > runargs;
    Array<const char* > objfiles;
    Array<const char* > linkswitches;
    Array<bool > linkswitchIsForCC;
    Array<const char* > libfiles;
    Array<const char* > dllfiles;
    _d_dynamicArray< const char > deffile;
    _d_dynamicArray< const char > resfile;
    _d_dynamicArray< const char > exefile;
    _d_dynamicArray< const char > mapfile;
    Param() :
        obj(true),
        link(true),
        dll(),
        lib(),
        multiobj(),
        oneobj(),
        trace(),
        tracegc(),
        verbose(),
        vcg_ast(),
        showColumns(),
        vtls(),
        vtemplates(),
        vtemplatesListInstances(),
        vgc(),
        vfield(),
        vcomplex(true),
        vin(),
        symdebug(),
        symdebugref(),
        optimize(),
        useDeprecated((DiagnosticReporting)1u),
        stackstomp(),
        useUnitTests(),
        useInline(false),
        useDIP1021(),
        release(),
        preservePaths(),
        warnings((DiagnosticReporting)2u),
        pic((PIC)0u),
        color(),
        cov(),
        covPercent(),
        ctfe_cov(false),
        nofloat(),
        ignoreUnsupportedPragmas(),
        useModuleInfo(true),
        useTypeInfo(true),
        useExceptions(true),
        noSharedAccess(),
        previewIn(),
        shortenedMethods(),
        betterC(),
        addMain(),
        allInst(),
        fix16997(true),
        fixAliasThis(),
        inclusiveInContracts(),
        ehnogc(),
        fieldwise(),
        cplusplus((CppStdRevision)201103u),
        markdown(true),
        vmarkdown(),
        showGaggedErrors(),
        printErrorContext(),
        manual(),
        usage(),
        mcpuUsage(),
        transitionUsage(),
        checkUsage(),
        checkActionUsage(),
        revertUsage(),
        previewUsage(),
        externStdUsage(),
        hcUsage(),
        logo(),
        useInvariants((CHECKENABLE)0u),
        useIn((CHECKENABLE)0u),
        useOut((CHECKENABLE)0u),
        useArrayBounds((CHECKENABLE)0u),
        useAssert((CHECKENABLE)0u),
        useSwitchError((CHECKENABLE)0u),
        boundscheck((CHECKENABLE)0u),
        checkAction((CHECKACTION)0u),
        errorLimit(20u),
        argv0(),
        modFileAliasStrings(),
        imppath(),
        fileImppath(),
        objdir(),
        objname(),
        libname(),
        doDocComments(),
        docdir(),
        docname(),
        ddocfiles(),
        doHdrGeneration(),
        hdrdir(),
        hdrname(),
        hdrStripPlainFunctions(true),
        cxxhdrdir(),
        cxxhdrname(),
        doJsonGeneration(),
        jsonfilename(),
        mixinOut(),
        mixinFile(),
        mixinLines(),
        debuglevel(),
        debugids(),
        versionlevel(),
        versionids(),
        defaultlibname(),
        debuglibname(),
        mscrtlib(),
        moduleDepsFile(),
        moduleDeps(),
        emitMakeDeps(),
        makeDepsFile(),
        makeDeps(),
        messageStyle((MessageStyle)0u),
        run(),
        runargs(),
        objfiles(),
        linkswitches(),
        linkswitchIsForCC(),
        libfiles(),
        dllfiles(),
        deffile(),
        resfile(),
        exefile(),
        mapfile()
    {
    }
    Param(bool obj, bool link = true, bool dll = false, bool lib = false, bool multiobj = false, bool oneobj = false, bool trace = false, bool tracegc = false, bool verbose = false, bool vcg_ast = false, bool showColumns = false, bool vtls = false, bool vtemplates = false, bool vtemplatesListInstances = false, bool vgc = false, bool vfield = false, bool vcomplex = true, bool vin = false, uint8_t symdebug = 0u, bool symdebugref = false, bool optimize = false, DiagnosticReporting useDeprecated = (DiagnosticReporting)1u, bool stackstomp = false, bool useUnitTests = false, bool useInline = false, FeatureState useDIP25 = (FeatureState)-1, FeatureState useDIP1000 = (FeatureState)-1, bool useDIP1021 = false, bool release = false, bool preservePaths = false, DiagnosticReporting warnings = (DiagnosticReporting)2u, PIC pic = (PIC)0u, bool color = false, bool cov = false, uint8_t covPercent = 0u, bool ctfe_cov = false, bool nofloat = false, bool ignoreUnsupportedPragmas = false, bool useModuleInfo = true, bool useTypeInfo = true, bool useExceptions = true, bool noSharedAccess = false, bool previewIn = false, bool shortenedMethods = false, bool betterC = false, bool addMain = false, bool allInst = false, bool fix16997 = true, bool fixAliasThis = false, bool inclusiveInContracts = false, bool ehnogc = false, FeatureState dtorFields = (FeatureState)-1, bool fieldwise = false, FeatureState rvalueRefParam = (FeatureState)-1, CppStdRevision cplusplus = (CppStdRevision)201103u, bool markdown = true, bool vmarkdown = false, bool showGaggedErrors = false, bool printErrorContext = false, bool manual = false, bool usage = false, bool mcpuUsage = false, bool transitionUsage = false, bool checkUsage = false, bool checkActionUsage = false, bool revertUsage = false, bool previewUsage = false, bool externStdUsage = false, bool hcUsage = false, bool logo = false, 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, uint32_t errorLimit = 20u, _d_dynamicArray< const char > argv0 = {}, Array<const char* > modFileAliasStrings = Array<const char* >(), Array<const char* >* imppath = nullptr, Array<const char* >* fileImppath = nullptr, _d_dynamicArray< const char > objdir = {}, _d_dynamicArray< const char > objname = {}, _d_dynamicArray< const char > libname = {}, bool doDocComments = false, _d_dynamicArray< const char > docdir = {}, _d_dynamicArray< const char > docname = {}, Array<const char* > ddocfiles = Array<const char* >(), bool doHdrGeneration = false, _d_dynamicArray< const char > hdrdir = {}, _d_dynamicArray< const char > hdrname = {}, bool hdrStripPlainFunctions = true, CxxHeaderMode doCxxHdrGeneration = (CxxHeaderMode)0u, _d_dynamicArray< const char > cxxhdrdir = {}, _d_dynamicArray< const char > cxxhdrname = {}, bool doJsonGeneration = false, _d_dynamicArray< const char > jsonfilename = {}, JsonFieldFlags jsonFieldFlags = (JsonFieldFlags)0u, OutBuffer* mixinOut = nullptr, const char* mixinFile = nullptr, int32_t mixinLines = 0, uint32_t debuglevel = 0u, Array<const char* >* debugids = nullptr, uint32_t versionlevel = 0u, Array<const char* >* versionids = nullptr, _d_dynamicArray< const char > defaultlibname = {}, _d_dynamicArray< const char > debuglibname = {}, _d_dynamicArray< const char > mscrtlib = {}, _d_dynamicArray< const char > moduleDepsFile = {}, OutBuffer* moduleDeps = nullptr, bool emitMakeDeps = false, _d_dynamicArray< const char > makeDepsFile = {}, Array<const char* > makeDeps = Array<const char* >(), MessageStyle messageStyle = (MessageStyle)0u, bool run = false, Array<const char* > runargs = Array<const char* >(), 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),
        link(link),
        dll(dll),
        lib(lib),
        multiobj(multiobj),
        oneobj(oneobj),
        trace(trace),
        tracegc(tracegc),
        verbose(verbose),
        vcg_ast(vcg_ast),
        showColumns(showColumns),
        vtls(vtls),
        vtemplates(vtemplates),
        vtemplatesListInstances(vtemplatesListInstances),
        vgc(vgc),
        vfield(vfield),
        vcomplex(vcomplex),
        vin(vin),
        symdebug(symdebug),
        symdebugref(symdebugref),
        optimize(optimize),
        useDeprecated(useDeprecated),
        stackstomp(stackstomp),
        useUnitTests(useUnitTests),
        useInline(useInline),
        useDIP25(useDIP25),
        useDIP1000(useDIP1000),
        useDIP1021(useDIP1021),
        release(release),
        preservePaths(preservePaths),
        warnings(warnings),
        pic(pic),
        color(color),
        cov(cov),
        covPercent(covPercent),
        ctfe_cov(ctfe_cov),
        nofloat(nofloat),
        ignoreUnsupportedPragmas(ignoreUnsupportedPragmas),
        useModuleInfo(useModuleInfo),
        useTypeInfo(useTypeInfo),
        useExceptions(useExceptions),
        noSharedAccess(noSharedAccess),
        previewIn(previewIn),
        shortenedMethods(shortenedMethods),
        betterC(betterC),
        addMain(addMain),
        allInst(allInst),
        fix16997(fix16997),
        fixAliasThis(fixAliasThis),
        inclusiveInContracts(inclusiveInContracts),
        ehnogc(ehnogc),
        dtorFields(dtorFields),
        fieldwise(fieldwise),
        rvalueRefParam(rvalueRefParam),
        cplusplus(cplusplus),
        markdown(markdown),
        vmarkdown(vmarkdown),
        showGaggedErrors(showGaggedErrors),
        printErrorContext(printErrorContext),
        manual(manual),
        usage(usage),
        mcpuUsage(mcpuUsage),
        transitionUsage(transitionUsage),
        checkUsage(checkUsage),
        checkActionUsage(checkActionUsage),
        revertUsage(revertUsage),
        previewUsage(previewUsage),
        externStdUsage(externStdUsage),
        hcUsage(hcUsage),
        logo(logo),
        useInvariants(useInvariants),
        useIn(useIn),
        useOut(useOut),
        useArrayBounds(useArrayBounds),
        useAssert(useAssert),
        useSwitchError(useSwitchError),
        boundscheck(boundscheck),
        checkAction(checkAction),
        errorLimit(errorLimit),
        argv0(argv0),
        modFileAliasStrings(modFileAliasStrings),
        imppath(imppath),
        fileImppath(fileImppath),
        objdir(objdir),
        objname(objname),
        libname(libname),
        doDocComments(doDocComments),
        docdir(docdir),
        docname(docname),
        ddocfiles(ddocfiles),
        doHdrGeneration(doHdrGeneration),
        hdrdir(hdrdir),
        hdrname(hdrname),
        hdrStripPlainFunctions(hdrStripPlainFunctions),
        doCxxHdrGeneration(doCxxHdrGeneration),
        cxxhdrdir(cxxhdrdir),
        cxxhdrname(cxxhdrname),
        doJsonGeneration(doJsonGeneration),
        jsonfilename(jsonfilename),
        jsonFieldFlags(jsonFieldFlags),
        mixinOut(mixinOut),
        mixinFile(mixinFile),
        mixinLines(mixinLines),
        debuglevel(debuglevel),
        debugids(debugids),
        versionlevel(versionlevel),
        versionids(versionids),
        defaultlibname(defaultlibname),
        debuglibname(debuglibname),
        mscrtlib(mscrtlib),
        moduleDepsFile(moduleDepsFile),
        moduleDeps(moduleDeps),
        emitMakeDeps(emitMakeDeps),
        makeDepsFile(makeDepsFile),
        makeDeps(makeDeps),
        messageStyle(messageStyle),
        run(run),
        runargs(runargs),
        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;
    _d_dynamicArray< const char > vendor;
    Param params;
    uint32_t errors;
    uint32_t warnings;
    uint32_t gag;
    uint32_t gaggedErrors;
    uint32_t gaggedWarnings;
    void* console;
    Array<Identifier* >* versionids;
    Array<Identifier* >* debugids;
    bool hasMainFunction;
    uint32_t varSequenceNumber;
    FileManager* fileManager;
    enum : int32_t { recursionLimit = 500 };

    uint32_t startGagging();
    bool endGagging(uint32_t oldGagged);
    void increaseErrorCount();
    void _init();
    uint32_t versionNumber();
    const char* const versionChars();
    Global() :
        inifilename(),
        copyright(73, "Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved"),
        written(24, "written by Walter Bright"),
        path(),
        filePath(),
        vendor(),
        params(),
        errors(),
        warnings(),
        gag(),
        gaggedErrors(),
        gaggedWarnings(),
        console(),
        versionids(),
        debugids(),
        hasMainFunction(),
        varSequenceNumber(1u),
        fileManager()
    {
    }
    Global(_d_dynamicArray< const char > inifilename, _d_dynamicArray< const char > copyright = { 73, "Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved" }, _d_dynamicArray< const char > written = { 24, "written by Walter Bright" }, Array<const char* >* path = nullptr, Array<const char* >* filePath = nullptr, _d_dynamicArray< const char > vendor = {}, 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 = nullptr, Array<Identifier* >* debugids = nullptr, bool hasMainFunction = false, uint32_t varSequenceNumber = 1u, FileManager* fileManager = nullptr) :
        inifilename(inifilename),
        copyright(copyright),
        written(written),
        path(path),
        filePath(filePath),
        vendor(vendor),
        params(params),
        errors(errors),
        warnings(warnings),
        gag(gag),
        gaggedErrors(gaggedErrors),
        gaggedWarnings(gaggedWarnings),
        console(console),
        versionids(versionids),
        debugids(debugids),
        hasMainFunction(hasMainFunction),
        varSequenceNumber(varSequenceNumber),
        fileManager(fileManager)
        {}
};

extern Global global;

struct Loc final
{
    const char* filename;
    uint32_t linnum;
    uint32_t charnum;
    const char* toChars(bool showColumns = global.params.showColumns, uint8_t messageStyle = static_cast<uint8_t>(global.params.messageStyle)) const;
    bool equals(const Loc& loc) const;
    Loc() :
        filename(),
        linnum(),
        charnum()
    {
    }
};

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

class Dsymbol : public ASTNode
{
public:
    Identifier* ident;
    Dsymbol* parent;
    CPPNamespaceDeclaration* cppnamespace;
    Symbol* csym;
    const Loc loc;
    Scope* _scope;
    const char* prettystring;
    bool errors;
    PASS semanticRun;
    uint16_t localNum;
    DeprecatedDeclaration* depdecl;
    UserAttributeDeclaration* userAttribDecl;
    static Dsymbol* create(Identifier* ident);
    const char* toChars() const;
    virtual const char* toPrettyCharsHelper();
    const Loc getLoc();
    const char* locToChars();
    bool equals(const RootObject* const o) const;
    bool isAnonymous() const;
    void error(const Loc& loc, const char* format, ...);
    void error(const char* format, ...);
    void deprecation(const Loc& loc, const char* format, ...);
    void deprecation(const char* format, ...);
    bool checkDeprecated(const Loc& loc, Scope* sc);
    Module* getModule();
    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;
    virtual Identifier* getIdent();
    virtual const char* toPrettyChars(bool QualifyTypes = false);
    virtual const char* kind() const;
    virtual Dsymbol* toAlias();
    virtual Dsymbol* toAlias2();
    virtual void addMember(Scope* sc, ScopeDsymbol* sds);
    virtual void setScope(Scope* sc);
    virtual void importAll(Scope* sc);
    virtual Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 0);
    virtual bool overloadInsert(Dsymbol* s);
    virtual 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 void setFieldOffset(AggregateDeclaration* ad, FieldState& fieldState, bool isunion);
    virtual bool hasPointers();
    virtual bool hasStaticCtorOrDtor();
    virtual void addLocalClass(Array<ClassDeclaration* >* _param_0);
    virtual void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories);
    virtual void checkCtorConstInit();
    virtual void addComment(const char* comment);
    const char* comment();
    void comment(const char* comment);
    UnitTestDeclaration* ddocUnittest();
    void ddocUnittest(UnitTestDeclaration* utd);
    bool inNonRoot();
    static void deinitialize();
    void accept(Visitor* v);
    virtual Package* isPackage();
    virtual Module* isModule();
    virtual EnumMember* isEnumMember();
    virtual TemplateDeclaration* isTemplateDeclaration();
    virtual TemplateInstance* isTemplateInstance();
    virtual TemplateMixin* isTemplateMixin();
    virtual ForwardingAttribDeclaration* isForwardingAttribDeclaration();
    virtual Nspace* isNspace();
    virtual Declaration* isDeclaration();
    virtual StorageClassDeclaration* isStorageClassDeclaration();
    virtual ExpressionDsymbol* isExpressionDsymbol();
    virtual AliasAssign* isAliasAssign();
    virtual ThisDeclaration* isThisDeclaration();
    virtual 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 CompileDeclaration* isCompileDeclaration();
    virtual StaticAssert* isStaticAssert();
};

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

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

typedef uint64_t StorageClass;

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

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

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

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 BE
{
    none = 0,
    fallthru = 1,
    throw_ = 2,
    return_ = 4,
    goto_ = 8,
    halt = 16,
    break_ = 32,
    continue_ = 64,
    errthrow = 128,
    any = 31,
};

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

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

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

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

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:
    const EXP op;
    uint8_t size;
    uint8_t parens;
    Type* type;
    Loc loc;
    static void _init();
    static void deinitialize();
    Expression* copy();
    virtual Expression* syntaxCopy();
    DYNCAST dyncast() const;
    const char* toChars() const;
    void error(const char* format, ...) const;
    void errorSupplemental(const char* format, ...);
    void warning(const char* format, ...) const;
    void deprecation(const char* format, ...) const;
    virtual dinteger_t toInteger();
    virtual uinteger_t toUInteger();
    virtual _d_real toReal();
    virtual _d_real toImaginary();
    virtual complex_t toComplex();
    virtual StringExp* toStringExp();
    virtual bool isLvalue();
    virtual Expression* toLvalue(Scope* sc, Expression* e);
    virtual Expression* modifiableLvalue(Scope* sc, Expression* e);
    Expression* implicitCastTo(Scope* sc, Type* t);
    MATCH implicitConvTo(Type* t);
    Expression* castTo(Scope* sc, Type* t);
    virtual Expression* resolveLoc(const Loc& loc, Scope* sc);
    virtual bool checkType();
    virtual bool checkValue();
    bool checkDeprecated(Scope* sc, Dsymbol* s);
    virtual Expression* addDtorHook(Scope* sc);
    Expression* addressOf();
    Expression* deref();
    Expression* optimize(int32_t result, bool keepLvalue = false);
    Expression* ctfeInterpret();
    int32_t isConst();
    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();
    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();
    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);
};

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

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

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

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

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,
    TMAX = 48u,
};

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

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

private:
    Mcache* mcache;
public:
    Type* pto;
    Type* rto;
    Type* arrayof;
    TypeInfoDeclaration* vtinfo;
    TYPE* ctype;
    static Type* tvoid;
    static Type* tint8;
    static Type* tuns8;
    static Type* tint16;
    static Type* tuns16;
    static Type* tint32;
    static Type* tuns32;
    static Type* tint64;
    static Type* tuns64;
    static Type* tint128;
    static Type* tuns128;
    static Type* tfloat32;
    static Type* tfloat64;
    static Type* tfloat80;
    static Type* timaginary32;
    static Type* timaginary64;
    static Type* timaginary80;
    static Type* tcomplex32;
    static Type* tcomplex64;
    static Type* tcomplex80;
    static Type* tbool;
    static Type* tchar;
    static Type* twchar;
    static Type* tdchar;
    static Type* tshiftcnt;
    static Type* tvoidptr;
    static Type* tstring;
    static Type* twstring;
    static Type* tdstring;
    static Type* terror;
    static Type* tnull;
    static Type* 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;
    bool equivalent(Type* t);
    DYNCAST dyncast() const;
    size_t getUniqueID() const;
    Covariant covariant(Type* t, uint64_t* pstc = nullptr);
    const char* toChars() const;
    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();
    Type* trySemantic(const Loc& loc, Scope* sc);
    Type* merge2();
    void modToBuffer(OutBuffer* buf) const;
    char* modToChars() const;
    virtual bool isintegral();
    virtual bool isfloating();
    virtual bool isreal();
    virtual bool isimaginary();
    virtual bool iscomplex();
    virtual bool isscalar();
    virtual bool isunsigned();
    virtual bool isscope();
    virtual bool isString();
    virtual bool isAssignable();
    virtual bool isBoolean();
    virtual void checkDeprecated(const Loc& loc, Scope* sc);
    bool isConst() const;
    bool isImmutable() const;
    bool isMutable() const;
    bool isShared() const;
    bool isSharedConst() const;
    bool isWild() const;
    bool isWildConst() const;
    bool isSharedWild() const;
    bool isNaked() const;
    Type* nullAttributes() const;
    Type* constOf();
    Type* immutableOf();
    Type* mutableOf();
    Type* sharedOf();
    Type* sharedConstOf();
    Type* unSharedOf();
    Type* wildOf();
    Type* wildConstOf();
    Type* sharedWildOf();
    Type* sharedWildConstOf();
    void fixTo(Type* t);
    void check();
    Type* addSTC(StorageClass stc);
    Type* castMod(uint8_t mod);
    Type* addMod(uint8_t mod);
    virtual Type* addStorageClass(StorageClass stc);
    Type* pointerTo();
    Type* referenceTo();
    Type* arrayOf();
    Type* sarrayOf(dinteger_t dim);
    bool hasDeprecatedAliasThis();
    Type* aliasthisOf();
    virtual Type* makeConst();
    virtual Type* makeImmutable();
    virtual Type* makeShared();
    virtual Type* makeSharedConst();
    virtual Type* makeWild();
    virtual Type* makeWildConst();
    virtual Type* makeSharedWild();
    virtual Type* makeSharedWildConst();
    virtual Type* makeMutable();
    virtual Dsymbol* toDsymbol(Scope* sc);
    Type* toBasetype();
    virtual bool isBaseOf(Type* t, int32_t* poffset);
    virtual MATCH implicitConvTo(Type* to);
    virtual MATCH constConv(Type* to);
    virtual uint8_t deduceWild(Type* t, bool isRef);
    virtual Type* substWildTo(uint32_t mod);
    Type* unqualify(uint32_t m);
    virtual Type* toHeadMutable();
    virtual ClassDeclaration* isClassHandle();
    virtual structalign_t alignment();
    virtual Expression* defaultInitLiteral(const Loc& loc);
    virtual bool isZeroInit(const Loc& loc);
    Identifier* getTypeInfoIdent();
    virtual int32_t hasWild() const;
    virtual bool hasPointers();
    virtual bool hasVoidInitPointers();
    virtual bool hasInvariant();
    virtual Type* nextOf();
    Type* baseElemOf();
    uint32_t numberOfElems(const Loc& loc);
    uinteger_t sizemask();
    virtual bool needsDestruction();
    virtual bool needsCopyOrPostblit();
    virtual bool needsNested();
    virtual TypeBasic* isTypeBasic();
    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);
    TypeFunction* toTypeFunction();
};

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

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,
    this_ = 88u,
    super_ = 89u,
    error = 90u,
    void_ = 91u,
    int8 = 92u,
    uns8 = 93u,
    int16 = 94u,
    uns16 = 95u,
    int32 = 96u,
    uns32 = 97u,
    int64 = 98u,
    uns64 = 99u,
    int128 = 100u,
    uns128 = 101u,
    float32 = 102u,
    float64 = 103u,
    float80 = 104u,
    imaginary32 = 105u,
    imaginary64 = 106u,
    imaginary80 = 107u,
    complex32 = 108u,
    complex64 = 109u,
    complex80 = 110u,
    char_ = 111u,
    wchar_ = 112u,
    dchar_ = 113u,
    bool_ = 114u,
    struct_ = 115u,
    class_ = 116u,
    interface_ = 117u,
    union_ = 118u,
    enum_ = 119u,
    import_ = 120u,
    alias_ = 121u,
    override_ = 122u,
    delegate_ = 123u,
    function_ = 124u,
    mixin_ = 125u,
    align_ = 126u,
    extern_ = 127u,
    private_ = 128u,
    protected_ = 129u,
    public_ = 130u,
    export_ = 131u,
    static_ = 132u,
    final_ = 133u,
    const_ = 134u,
    abstract_ = 135u,
    debug_ = 136u,
    deprecated_ = 137u,
    in_ = 138u,
    out_ = 139u,
    inout_ = 140u,
    lazy_ = 141u,
    auto_ = 142u,
    package_ = 143u,
    immutable_ = 144u,
    if_ = 145u,
    else_ = 146u,
    while_ = 147u,
    for_ = 148u,
    do_ = 149u,
    switch_ = 150u,
    case_ = 151u,
    default_ = 152u,
    break_ = 153u,
    continue_ = 154u,
    with_ = 155u,
    synchronized_ = 156u,
    return_ = 157u,
    goto_ = 158u,
    try_ = 159u,
    catch_ = 160u,
    finally_ = 161u,
    asm_ = 162u,
    foreach_ = 163u,
    foreach_reverse_ = 164u,
    scope_ = 165u,
    onScopeExit = 166u,
    onScopeFailure = 167u,
    onScopeSuccess = 168u,
    invariant_ = 169u,
    unittest_ = 170u,
    argumentTypes = 171u,
    ref_ = 172u,
    macro_ = 173u,
    parameters = 174u,
    traits = 175u,
    pure_ = 176u,
    nothrow_ = 177u,
    gshared = 178u,
    line = 179u,
    file = 180u,
    fileFullPath = 181u,
    moduleString = 182u,
    functionString = 183u,
    prettyFunction = 184u,
    shared_ = 185u,
    at = 186u,
    pow = 187u,
    powAssign = 188u,
    goesTo = 189u,
    vector = 190u,
    pound = 191u,
    arrow = 192u,
    colonColon = 193u,
    wchar_tLiteral = 194u,
    endOfLine = 195u,
    whitespace = 196u,
    inline_ = 197u,
    register_ = 198u,
    restrict = 199u,
    signed_ = 200u,
    sizeof_ = 201u,
    typedef_ = 202u,
    unsigned_ = 203u,
    volatile_ = 204u,
    _Alignas = 205u,
    _Alignof = 206u,
    _Atomic = 207u,
    _Bool = 208u,
    _Complex_ = 209u,
    _Generic = 210u,
    _Imaginary = 211u,
    _Noreturn = 212u,
    _Static_assert = 213u,
    _Thread_local = 214u,
    _import = 215u,
    __cdecl_ = 216u,
    __declspec_ = 217u,
    __stdcall_ = 218u,
    __attribute___ = 219u,
};

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

template <typename AST>
class ParseTimeVisitor
{
public:
    virtual void visit(typename AST::Dsymbol );
    virtual void visit(typename AST::Parameter );
    virtual void visit(typename AST::Statement );
    virtual void visit(typename AST::Type );
    virtual void visit(typename AST::Expression );
    virtual void visit(typename AST::TemplateParameter );
    virtual void visit(typename AST::Condition );
    virtual void visit(typename AST::Initializer );
    virtual void visit(typename AST::AliasThis s);
    virtual void visit(typename AST::Declaration s);
    virtual void visit(typename AST::ScopeDsymbol s);
    virtual void visit(typename AST::Import s);
    virtual void visit(typename AST::AttribDeclaration s);
    virtual void visit(typename AST::StaticAssert s);
    virtual void visit(typename AST::DebugSymbol s);
    virtual void visit(typename AST::VersionSymbol s);
    virtual void visit(typename AST::AliasAssign s);
    virtual void visit(typename AST::Package s);
    virtual void visit(typename AST::EnumDeclaration s);
    virtual void visit(typename AST::AggregateDeclaration s);
    virtual void visit(typename AST::TemplateDeclaration s);
    virtual void visit(typename AST::TemplateInstance s);
    virtual void visit(typename AST::Nspace s);
    virtual void visit(typename AST::VarDeclaration s);
    virtual void visit(typename AST::FuncDeclaration s);
    virtual void visit(typename AST::AliasDeclaration s);
    virtual void visit(typename AST::TupleDeclaration s);
    virtual void visit(typename AST::FuncLiteralDeclaration s);
    virtual void visit(typename AST::PostBlitDeclaration s);
    virtual void visit(typename AST::CtorDeclaration s);
    virtual void visit(typename AST::DtorDeclaration s);
    virtual void visit(typename AST::InvariantDeclaration s);
    virtual void visit(typename AST::UnitTestDeclaration s);
    virtual void visit(typename AST::NewDeclaration s);
    virtual void visit(typename AST::StaticCtorDeclaration s);
    virtual void visit(typename AST::StaticDtorDeclaration s);
    virtual void visit(typename AST::SharedStaticCtorDeclaration s);
    virtual void visit(typename AST::SharedStaticDtorDeclaration s);
    virtual void visit(typename AST::CompileDeclaration s);
    virtual void visit(typename AST::UserAttributeDeclaration s);
    virtual void visit(typename AST::LinkDeclaration s);
    virtual void visit(typename AST::AnonDeclaration s);
    virtual void visit(typename AST::AlignDeclaration s);
    virtual void visit(typename AST::CPPMangleDeclaration s);
    virtual void visit(typename AST::CPPNamespaceDeclaration s);
    virtual void visit(typename AST::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::CompileStatement s);
    virtual void visit(typename AST::WhileStatement s);
    virtual void visit(typename AST::ForStatement s);
    virtual void visit(typename AST::DoStatement s);
    virtual void visit(typename AST::ForeachRangeStatement s);
    virtual void visit(typename AST::ForeachStatement s);
    virtual void visit(typename AST::IfStatement s);
    virtual void visit(typename AST::ScopeGuardStatement s);
    virtual void visit(typename AST::ConditionalStatement s);
    virtual void visit(typename AST::StaticForeachStatement s);
    virtual void visit(typename AST::PragmaStatement s);
    virtual void visit(typename AST::SwitchStatement s);
    virtual void visit(typename AST::CaseRangeStatement s);
    virtual void visit(typename AST::CaseStatement s);
    virtual void visit(typename AST::DefaultStatement s);
    virtual void visit(typename AST::BreakStatement s);
    virtual void visit(typename AST::ContinueStatement s);
    virtual void visit(typename AST::GotoDefaultStatement s);
    virtual void visit(typename AST::GotoCaseStatement s);
    virtual void visit(typename AST::GotoStatement s);
    virtual void visit(typename AST::SynchronizedStatement s);
    virtual void visit(typename AST::WithStatement s);
    virtual void visit(typename AST::TryCatchStatement s);
    virtual void visit(typename AST::TryFinallyStatement s);
    virtual void visit(typename AST::ThrowStatement s);
    virtual void visit(typename AST::AsmStatement s);
    virtual void visit(typename AST::ExpStatement s);
    virtual void visit(typename AST::CompoundStatement s);
    virtual void visit(typename AST::CompoundDeclarationStatement s);
    virtual void visit(typename AST::CompoundAsmStatement s);
    virtual void visit(typename AST::InlineAsmStatement s);
    virtual void visit(typename AST::GccAsmStatement s);
    virtual void visit(typename AST::TypeBasic t);
    virtual void visit(typename AST::TypeError t);
    virtual void visit(typename AST::TypeNull t);
    virtual void visit(typename AST::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::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::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::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,
};

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 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
{
    IgnoreNone = 0,
    IgnorePrivateImports = 1,
    IgnoreErrors = 2,
    IgnoreAmbiguous = 4,
    SearchLocalsOnly = 8,
    SearchImportsOnly = 16,
    SearchUnqualifiedModule = 32,
    IgnoreSymbolVisibility = 128,
    TagNameSpace = 256,
};

enum : int32_t { IDX_NOTFOUND = 305419896 };

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

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

enum : bool { LOGSEMANTIC = false };

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

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

enum : int32_t { WANTexpand = 1 };

enum : int32_t { WANTvalue = 0 };

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

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

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

enum class ILS : uint8_t
{
    uninitialized = 0u,
    no = 1u,
    yes = 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,
};

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:
    Array<Statement* >* frequires;
    Array<Ensure >* fensures;
    Statement* frequire;
    Statement* fensure;
    Statement* fbody;
    Array<FuncDeclaration* > foverrides;
    FuncDeclaration* fdrequire;
    FuncDeclaration* fdensure;
    Array<Expression* >* fdrequireParams;
    Array<Expression* >* fdensureParams;
    const char* mangleString;
    VarDeclaration* vresult;
    LabelDsymbol* returnLabel;
    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;
    BUILTIN builtin;
    int32_t tookAddressOf;
    bool requiresClosure;
    Array<VarDeclaration* > closureVars;
    Array<VarDeclaration* > outerVars;
    Array<FuncDeclaration* > siblingCallers;
    Array<FuncDeclaration* >* inlinedNestedCallees;
    uint32_t flags;
    ObjcFuncDeclaration objc;
    static FuncDeclaration* create(const Loc& loc, const Loc& endloc, Identifier* id, StorageClass storage_class, Type* type, bool noreturn = false);
    FuncDeclaration* syntaxCopy(Dsymbol* s);
    bool functionSemantic();
    bool functionSemantic3();
    bool equals(const RootObject* const o) const;
    int32_t overrides(FuncDeclaration* fd);
    int32_t findVtblIndex(Array<Dsymbol* >* vtbl, int32_t dim);
    BaseClass* overrideInterface();
    bool overloadInsert(Dsymbol* s);
    bool inUnittest();
    MATCH leastAsSpecialized(FuncDeclaration* g);
    LabelDsymbol* searchLabel(Identifier* ident, const Loc& loc = Loc::initial);
    int32_t getLevel(FuncDeclaration* fd, int32_t intypeof);
    int32_t getLevelAndCheck(const Loc& loc, Scope* sc, FuncDeclaration* fd, Declaration* decl);
    enum : int32_t { LevelError = -2 };

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

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

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

enum class FUNCFLAG : uint32_t
{
    purityInprocess = 1u,
    safetyInprocess = 2u,
    nothrowInprocess = 4u,
    nogcInprocess = 8u,
    returnInprocess = 16u,
    inlineScanned = 32u,
    inferScope = 64u,
    hasCatches = 128u,
    compileTimeOnly = 256u,
    printf = 512u,
    scanf = 1024u,
    noreturn = 2048u,
    NRVO = 4096u,
    naked = 8192u,
    generated = 16384u,
    introducing = 32768u,
    semantic3Errors = 65536u,
    noEH = 131072u,
    inferRetType = 262144u,
    dualContext = 524288u,
    hasAlwaysInline = 1048576u,
    CRTCtor = 2097152u,
    CRTDtor = 4194304u,
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

enum : int32_t { TEST_EMIT_ALL = 0 };

extern void genhdrfile(Module* m);

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

extern const char* parametersTypeToChars(ParameterList pl);

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

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

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

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

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

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

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

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

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

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

extern Expression* initializerToExpression(Initializer* init, Type* itype = nullptr, const bool isCfile = false);

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

enum : int32_t { LOGDEFAULTINIT = 0 };

enum : int32_t { LOGDOTEXP = 0 };

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

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;
    void checkDeprecated(const Loc& loc, Scope* sc);
    int32_t hasWild() const;
    Type* nextOf();
    Type* makeConst();
    Type* makeImmutable();
    Type* makeShared();
    Type* makeSharedConst();
    Type* makeWild();
    Type* makeWildConst();
    Type* makeSharedWild();
    Type* makeSharedWildConst();
    Type* makeMutable();
    MATCH constConv(Type* to);
    uint8_t deduceWild(Type* t, bool isRef);
    void transitive();
    void accept(Visitor* v);
};

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

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

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

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;
    uinteger_t size(const Loc& loc) /* const */;
    TypeClass* syntaxCopy();
    Dsymbol* toDsymbol(Scope* sc);
    ClassDeclaration* isClassHandle();
    bool isBaseOf(Type* t, int32_t* poffset);
    MATCH implicitConvTo(Type* to);
    MATCH constConv(Type* to);
    uint8_t deduceWild(Type* t, bool isRef);
    Type* toHeadMutable();
    bool isZeroInit(const Loc& loc) /* const */;
    bool isscope() /* const */;
    bool isBoolean() /* const */;
    bool hasPointers() /* const */;
    void accept(Visitor* v);
};

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

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

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

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

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;
    Array<Expression* >* fargs;
    static TypeFunction* create(Array<Parameter* >* parameters, Type* treturn, uint8_t varargs, LINK linkage, StorageClass stc = 0);
    const char* kind() const;
    TypeFunction* syntaxCopy();
    void purityLevel();
    bool hasLazyParameters();
    bool isDstyleVariadic() const;
    StorageClass parameterStorageClass(Type* tthis, Parameter* p);
    Type* addStorageClass(StorageClass stc);
    Type* substWildTo(uint32_t _param_0);
    MATCH constConv(Type* to);
    bool iswild() const;
    bool attributesEqual(const TypeFunction* const other) const;
    void accept(Visitor* v);
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

extern AggregateDeclaration* isAggregate(Type* t);

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

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

class Statement : public ASTNode
{
public:
    const Loc loc;
    const STMT stmt;
    DYNCAST dyncast() const;
    virtual Statement* syntaxCopy();
    static Array<Statement* >* arraySyntaxCopy(Array<Statement* >* a);
    const char* toChars() const;
    void error(const char* format, ...);
    void warning(const char* format, ...);
    void deprecation(const char* format, ...);
    virtual Statement* getRelatedLabeled();
    virtual bool hasBreak() const;
    virtual bool hasContinue() const;
    bool usesEH();
    bool comeFrom();
    bool hasCode();
    virtual Statement* last();
    void accept(Visitor* v);
    virtual ReturnStatement* endsWithReturnStatement();
    ErrorStatement* isErrorStatement();
    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();
    CompileStatement* isCompileStatement();
    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();
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

extern Expression* defaultInit(Type* mt, const Loc& loc, const bool isCfile = false);

extern Type* merge(Type* type);

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

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,
    templateparameter = 131072LLU,
    ref_ = 262144LLU,
    scope_ = 524288LLU,
    maybescope = 1048576LLU,
    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 = 268288LLU,
    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 CompileDeclaration = ::CompileDeclaration;
    using ConditionalDeclaration = ::ConditionalDeclaration;
    using DeprecatedDeclaration = ::DeprecatedDeclaration;
    using ForwardingAttribDeclaration = ::ForwardingAttribDeclaration;
    using LinkDeclaration = ::LinkDeclaration;
    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 Module = ::Module;
    using ModuleDeclaration = ::ModuleDeclaration;
    using Package = ::Package;
    using StructDeclaration = ::StructDeclaration;
    using StructFlags = ::StructFlags;
    using UnionDeclaration = ::UnionDeclaration;
    using AliasAssign = ::AliasAssign;
    using ArrayScopeSymbol = ::ArrayScopeSymbol;
    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 Ungag = ::Ungag;
    using Visibility = ::Visibility;
    using WithScopeSymbol = ::WithScopeSymbol;
    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 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 CallExp = ::CallExp;
    using CastExp = ::CastExp;
    using CatAssignExp = ::CatAssignExp;
    using CatDcharAssignExp = ::CatDcharAssignExp;
    using CatElemAssignExp = ::CatElemAssignExp;
    using CatExp = ::CatExp;
    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 IntervalExp = ::IntervalExp;
    using IsExp = ::IsExp;
    using LineInitExp = ::LineInitExp;
    using LogicalExp = ::LogicalExp;
    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 TraitsExp = ::TraitsExp;
    using TupleExp = ::TupleExp;
    using TypeExp = ::TypeExp;
    using TypeidExp = ::TypeidExp;
    using UAddExp = ::UAddExp;
    using UnaExp = ::UnaExp;
    using UnionExp = ::UnionExp;
    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 emplaceExp = ::emplaceExp;
    using fp2_t = ::fp2_t;
    using fp_t = ::fp_t;
    using BUILTIN = ::BUILTIN;
    using CtorDeclaration = ::CtorDeclaration;
    using DtorDeclaration = ::DtorDeclaration;
    using Ensure = ::Ensure;
    using FUNCFLAG = ::FUNCFLAG;
    using FuncAliasDeclaration = ::FuncAliasDeclaration;
    using FuncDeclaration = ::FuncDeclaration;
    using FuncLiteralDeclaration = ::FuncLiteralDeclaration;
    using FuncResolveFlag = ::FuncResolveFlag;
    using ILS = ::ILS;
    using InvariantDeclaration = ::InvariantDeclaration;
    using NewDeclaration = ::NewDeclaration;
    using NrvoWalker = ::NrvoWalker;
    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 DesigInit = ::DesigInit;
    using Designator = ::Designator;
    using ErrorInitializer = ::ErrorInitializer;
    using ExpInitializer = ::ExpInitializer;
    using Initializer = ::Initializer;
    using NeedInterpret = ::NeedInterpret;
    using StructInitializer = ::StructInitializer;
    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 Nspace = ::Nspace;
    using AsmStatement = ::AsmStatement;
    using BreakStatement = ::BreakStatement;
    using CaseRangeStatement = ::CaseRangeStatement;
    using CaseStatement = ::CaseStatement;
    using Catch = ::Catch;
    using CompileStatement = ::CompileStatement;
    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 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 WhileStatement = ::WhileStatement;
    using WithStatement = ::WithStatement;
    using StaticAssert = ::StaticAssert;
    using CTFEExp = ::CTFEExp;
    using ClassReferenceExp = ::ClassReferenceExp;
    using ThrownExceptionExp = ::ThrownExceptionExp;
    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 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);
};

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

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* mangleOverride;
    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);
    void setScope(Scope* sc);
    size_t nonHiddenFields();
    bool determineSize(const Loc& loc);
    virtual void finalizeSize() = 0;
    uinteger_t size(const Loc& loc);
    bool fill(const Loc& loc, Array<Expression* >* elements, bool ctorinit);
    Type* getType();
    bool isDeprecated() const;
    void setDeprecated();
    bool isNested() const;
    bool isExport() const;
    Dsymbol* searchCtor();
    Visibility visible();
    Type* handleType();
    bool hasInvariant();
    void* sinit;
    AggregateDeclaration* isAggregateDeclaration();
    void accept(Visitor* v);
};

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

extern TypeTuple* toArgTypes_x86(Type* t);

extern TypeTuple* toArgTypes_sysv_x64(Type* t);

extern TypeTuple* toArgTypes_aarch64(Type* t);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

extern BUILTIN isBuiltin(FuncDeclaration* fd);

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

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

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;
    virtual Condition* syntaxCopy() = 0;
    virtual int32_t include(Scope* sc) = 0;
    virtual DebugCondition* isDebugCondition();
    virtual VersionCondition* isVersionCondition();
    void accept(Visitor* v);
};

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

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

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

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

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

extern const char* toCppMangleItanium(Dsymbol* s);

extern const char* cppTypeInfoMangleItanium(Dsymbol* s);

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

extern const char* toCppMangleMSVC(Dsymbol* s);

extern const char* cppTypeInfoMangleMSVC(Dsymbol* s);

extern const char* toCppMangleDMC(Dsymbol* s);

extern const char* cppTypeInfoMangleDMC(Dsymbol* s);

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

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

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

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

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;
private:
    bool inuse;
public:
    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);
    ClassDeclaration* syntaxCopy(Dsymbol* s);
    Scope* newScope(Scope* sc);
    bool isBaseOf2(ClassDeclaration* cd);
    enum : int32_t { OFFSET_RUNTIME = 1985229328 };

    enum : int32_t { OFFSET_FWDREF = 1985229329 };

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

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

extern void ObjectNotFound(Identifier* id);

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

    Symbol* isym;
    _d_dynamicArray< const char > mangleOverride;
    const char* kind() const;
    uinteger_t size(const Loc& loc);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    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 isSynchronized() const;
    bool isParameter() const;
    bool isDeprecated() const;
    bool isDisabled() const;
    bool isOverride() const;
    bool isResult() const;
    bool isField() const;
    bool isIn() const;
    bool isOut() const;
    bool isRef() const;
    bool isReference() const;
    bool isFuture() const;
    Visibility visible();
    Declaration* isDeclaration();
    void accept(Visitor* v);
};

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

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

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

class VarDeclaration : public Declaration
{
public:
    Initializer* _init;
    Array<FuncDeclaration* > nestedrefs;
    Dsymbol* aliassym;
    VarDeclaration* lastVar;
    Expression* edtor;
    IntRange* range;
    Array<VarDeclaration* >* maybes;
    uint32_t endlinnum;
    uint32_t offset;
    uint32_t sequenceNumber;
    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 doNotInferScope() const;
    bool doNotInferScope(bool v);
    bool doNotInferReturn() const;
    bool doNotInferReturn(bool v);
    bool isArgDtorVar() const;
    bool isArgDtorVar(bool v);
private:
    uint16_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);
    void setFieldOffset(AggregateDeclaration* ad, FieldState& fieldState, bool isunion);
    const char* kind() const;
    AggregateDeclaration* isThis();
    bool needThis();
    bool isExport() const;
    bool isImportedSymbol() const;
    bool isCtorinit() const;
    bool isDataseg();
    bool isThreadlocal();
    bool isCTFE();
    bool isOverlappedWith(VarDeclaration* v);
    bool hasPointers();
    bool canTakeAddressOf();
    bool needsScopeDtor();
    void checkCtorConstInit();
    Dsymbol* toAlias();
    VarDeclaration* isVarDeclaration();
    void accept(Visitor* v);
};

class BitFieldDeclaration : public VarDeclaration
{
public:
    Expression* width;
    uint32_t fieldWidth;
    uint32_t bitOffset;
    BitFieldDeclaration* syntaxCopy(Dsymbol* s);
    BitFieldDeclaration* isBitFieldDeclaration();
    void accept(Visitor* v);
    void setFieldOffset(AggregateDeclaration* ad, FieldState& fieldState, bool isunion);
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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;
    Visibility visible();
    Import* syntaxCopy(Dsymbol* s);
    bool load(Scope* sc);
    void importAll(Scope* sc);
    Dsymbol* toAlias();
    void addMember(Scope* sc, ScopeDsymbol* sd);
    void setScope(Scope* sc);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    bool overloadInsert(Dsymbol* s);
    Import* isImport();
    void accept(Visitor* v);
};

extern Expression* getValue(VarDeclaration* vd);

extern void printCtfePerformanceStats();

struct MacroTable final
{
private:
    void* mactab;
public:
    MacroTable()
    {
    }
};

extern const char* mangleExact(FuncDeclaration* fd);

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

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

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

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

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

class Module final : public Package
{
public:
    static Module* rootModule;
    static DsymbolTable* modules;
    static Array<Module* > amodules;
    static Array<Dsymbol* > deferred;
    static Array<Dsymbol* > deferred2;
    static Array<Dsymbol* > deferred3;
    static uint32_t dprogress;
    static void _init();
    static void deinitialize();
    static AggregateDeclaration* moduleinfo;
    _d_dynamicArray< const char > arg;
    ModuleDeclaration* md;
    const FileName srcfile;
    const FileName objfile;
    const FileName hdrfile;
    FileName docfile;
    _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;
    int32_t selfimports;
    void* tagSymTab;
    bool selfImports();
    int32_t rootimports;
    bool rootImports();
    int32_t insearch;
    Identifier* searchCacheIdent;
    Dsymbol* searchCacheSymbol;
    int32_t searchCacheFlags;
    Module* importedFrom;
    Array<Dsymbol* >* decldefs;
    Array<Module* > aimports;
    uint32_t debuglevel;
    Array<Identifier* >* debugids;
    Array<Identifier* >* debugidsNot;
    uint32_t versionlevel;
    Array<Identifier* >* versionids;
    Array<Identifier* >* versionidsNot;
    MacroTable macrotable;
    Escape* _escapetable;
    size_t nameoffset;
    size_t namelen;
    static Module* create(const char* filename, Identifier* ident, int32_t doDocComment, int32_t doHdrGen);
    static Module* load(const Loc& loc, Array<Identifier* >* packages, Identifier* ident);
    const char* kind() const;
    bool read(const Loc& loc);
    Module* parse();
    void importAll(Scope* prevsc);
    int32_t needModuleInfo();
    void checkImportDeprecation(const Loc& loc, Scope* sc);
    Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
    bool isPackageAccessible(Package* p, Visibility visibility, int32_t flags = 0);
    Dsymbol* symtabInsert(Dsymbol* s);
    void deleteObjFile();
    static void runDeferredSemantic();
    static void runDeferredSemantic2();
    static void runDeferredSemantic3();
    int32_t imports(Module* m);
    bool isRoot();
    bool isCoreModule(Identifier* ident);
    int32_t doppelganger;
    Symbol* cov;
    uint32_t* covb;
    Symbol* sictor;
    Symbol* sctor;
    Symbol* sdtor;
    Symbol* ssharedctor;
    Symbol* sshareddtor;
    Symbol* stest;
    Symbol* sfilename;
    void* ctfe_cov;
    Module* isModule();
    void accept(Visitor* v);
    void fullyQualifiedName(OutBuffer& buf);
};

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

extern void gendocfile(Module* m);

extern FuncDeclaration* search_toString(StructDeclaration* sd);

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

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

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

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

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

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

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

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

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

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

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

extern Expression* isExpression(RootObject* o);

extern Dsymbol* isDsymbol(RootObject* o);

extern Type* isType(RootObject* o);

extern Tuple* isTuple(RootObject* o);

extern Parameter* isParameter(RootObject* o);

extern TemplateParameter* isTemplateParameter(RootObject* o);

extern bool isError(const RootObject* const o);

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

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;
    int32_t inuse;
    TemplatePrevious* previous;
private:
    Expression* lastConstraint;
    Array<Expression* > lastConstraintNegs;
    Array<RootObject* >* lastConstraintTiargs;
public:
    TemplateDeclaration* syntaxCopy(Dsymbol* _param_0);
    bool overloadInsert(Dsymbol* s);
    bool hasStaticCtorOrDtor();
    const char* kind() const;
    const char* toChars() const;
    const char* toCharsNoConstraints() const;
    const char* toCharsMaybeConstraints(bool includeConstraints) const;
    Visibility visible();
    const char* getConstraintEvalError(const char*& tip);
    Scope* scopeForTemplateParameters(TemplateInstance* ti, Scope* sc);
    MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration* td2, Array<Expression* >* fargs);
    RootObject* declareParameter(Scope* sc, TemplateParameter* tp, RootObject* o);
    TemplateDeclaration* isTemplateDeclaration();
    TemplateTupleParameter* isVariadic();
    bool isDeprecated() const;
    bool isOverloadable() const;
    void accept(Visitor* v);
};

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 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;
    DYNCAST dyncast() const;
    virtual RootObject* dummyArg() = 0;
    void accept(Visitor* v);
};

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

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

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

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

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

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

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

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

extern void printTemplateStats();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class StringExp final : public Expression
{
    union
    {
        char* string;
        char16_t* wstring;
        char32_t* dstring;
    };
public:
    size_t len;
    uint8_t sz;
    uint8_t committed;
    enum : char { NoPostfix = 0u };

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

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

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

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

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

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

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

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

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

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

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

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

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

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;
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    void accept(Visitor* v);
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class CallExp final : public UnaExp
{
public:
    Array<Expression* >* arguments;
    FuncDeclaration* f;
    bool directcall;
    bool inDebugStatement;
    bool ignoreAttributes;
    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();
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* addDtorHook(Scope* sc);
    void accept(Visitor* v);
};

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

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

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

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

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

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

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

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

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

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

class SliceExp final : public UnaExp
{
public:
    Expression* upr;
    Expression* lwr;
    VarDeclaration* lengthVar;
    bool upperIsInBounds;
    bool lowerIsLessThanUpper;
    bool arrayop;
    SliceExp* syntaxCopy();
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    Optional<bool > toBool();
    void accept(Visitor* v);
};

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

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

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

class CommaExp final : public BinExp
{
public:
    const bool isGenerated;
    bool allowCommaExp;
    bool isLvalue();
    Expression* toLvalue(Scope* sc, Expression* e);
    Expression* modifiableLvalue(Scope* sc, Expression* e);
    Optional<bool > toBool();
    Expression* addDtorHook(Scope* sc);
    void accept(Visitor* v);
    static void allow(Expression* exp);
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

extern JsonFieldFlags tryParseJsonField(const char* fieldName);

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

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

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

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

extern void semanticTypeInfoMembers(StructDeclaration* sd);

extern bool isTrivialExp(Expression* e);

extern bool hasSideEffect(Expression* e, bool assumeImpureCalls = false);

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

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

public:
    Expression* getTargetInfo(const char* name, const Loc& loc);
    bool isCalleeDestroyingArgs(TypeFunction* tf);
    bool libraryObjectMonitors(FuncDeclaration* fd, Statement* fbody);
    bool supportsLinkerDirective() const;
    Target() :
        os((OS)1u),
        osMajor(0u),
        ptrsize(),
        realsize(),
        realpad(),
        realalignsize(),
        classinfosize(),
        maxStaticDataSize(),
        c(),
        cpp(),
        objc(),
        architectureName(),
        cpu((CPU)11u),
        is64bit(true),
        isLP64(),
        obj_ext(),
        lib_ext(),
        dll_ext(),
        run_noext(),
        omfobj(false),
        FloatProperties(),
        DoubleProperties(),
        RealProperties()
    {
    }
    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)11u, bool is64bit = true, 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 >()) :
        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),
        is64bit(is64bit),
        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)
        {}
};

extern Target target;

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

extern void genTypeInfo(const Loc& loc, Type* torig, Scope* sc);

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

extern bool builtinTypeInfo(Type* t);

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

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 verror(const Loc& loc, const char* format, va_list ap, const char* p1 = nullptr, const char* p2 = nullptr, const char* header = "Error: ");

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

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

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

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

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

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

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

extern void fatal();

extern void halt();

struct Id final
{
    static Identifier* IUnknown;
    static Identifier* Object;
    static Identifier* object;
    static Identifier* string;
    static Identifier* wstring;
    static Identifier* dstring;
    static Identifier* max;
    static Identifier* min;
    static Identifier* This;
    static Identifier* _super;
    static Identifier* ctor;
    static Identifier* dtor;
    static Identifier* 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* p;
    static Identifier* gate;
    static Identifier* cpp_type_info_ptr;
    static Identifier* _assert;
    static Identifier* _unittest;
    static Identifier* _body;
    static Identifier* printf;
    static Identifier* scanf;
    static Identifier* TypeInfo;
    static Identifier* TypeInfo_Class;
    static Identifier* TypeInfo_Interface;
    static Identifier* TypeInfo_Struct;
    static Identifier* TypeInfo_Enum;
    static Identifier* TypeInfo_Pointer;
    static Identifier* TypeInfo_Vector;
    static Identifier* TypeInfo_Array;
    static Identifier* TypeInfo_StaticArray;
    static Identifier* TypeInfo_AssociativeArray;
    static Identifier* TypeInfo_Function;
    static Identifier* TypeInfo_Delegate;
    static Identifier* TypeInfo_Tuple;
    static Identifier* TypeInfo_Const;
    static Identifier* TypeInfo_Invariant;
    static Identifier* TypeInfo_Shared;
    static Identifier* TypeInfo_Wild;
    static Identifier* elements;
    static Identifier* _arguments_typeinfo;
    static Identifier* _arguments;
    static Identifier* _argptr;
    static Identifier* destroy;
    static Identifier* xopEquals;
    static Identifier* xopCmp;
    static Identifier* xtoHash;
    static Identifier* LINE;
    static Identifier* FILE;
    static Identifier* MODULE;
    static Identifier* FUNCTION;
    static Identifier* PRETTY_FUNCTION;
    static Identifier* DATE;
    static Identifier* TIME;
    static Identifier* TIMESTAMP;
    static Identifier* VENDOR;
    static Identifier* VERSIONX;
    static Identifier* EOFX;
    static Identifier* nan;
    static Identifier* infinity;
    static Identifier* dig;
    static Identifier* epsilon;
    static Identifier* mant_dig;
    static Identifier* max_10_exp;
    static Identifier* max_exp;
    static Identifier* min_10_exp;
    static Identifier* min_exp;
    static Identifier* min_normal;
    static Identifier* re;
    static Identifier* im;
    static Identifier* C;
    static Identifier* D;
    static Identifier* Windows;
    static Identifier* System;
    static Identifier* Objective;
    static Identifier* exit;
    static Identifier* success;
    static Identifier* failure;
    static Identifier* keys;
    static Identifier* values;
    static Identifier* rehash;
    static Identifier* future;
    static Identifier* property;
    static Identifier* nogc;
    static Identifier* live;
    static Identifier* safe;
    static Identifier* trusted;
    static Identifier* system;
    static Identifier* disable;
    static Identifier* _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* monitorenter;
    static Identifier* monitorexit;
    static Identifier* criticalenter;
    static Identifier* criticalexit;
    static Identifier* _d_delThrowable;
    static Identifier* _d_assert_fail;
    static Identifier* dup;
    static Identifier* _aaApply;
    static Identifier* _aaApply2;
    static Identifier* _d_arrayctor;
    static Identifier* _d_arraysetctor;
    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* stdc;
    static Identifier* stdarg;
    static Identifier* va_start;
    static Identifier* std;
    static Identifier* core;
    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* 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* 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* TRUE;
    static Identifier* FALSE;
    static Identifier* dllimport;
    static Identifier* dllexport;
    static Identifier* vector_size;
    static Identifier* noreturn;
    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 void initialize();
    Id()
    {
    }
};

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

struct Token final
{
    Token* next;
    Loc loc;
    const char* ptr;
    TOK value;
    _d_dynamicArray< const char > blockComment;
    _d_dynamicArray< const char > lineComment;
    union
    {
        int64_t intvalue;
        uinteger_t unsvalue;
        _d_real floatvalue;
        struct
        {
            const char* ustring;
            uint32_t len;
            uint8_t postfix;
        };
        Identifier* ident;
    };
    int32_t isKeyword() const;
    void setString(const char* ptr, size_t length);
    void setString(const OutBuffer& buf);
    void setString();
    const char* toChars() const;
    static const char* toChars(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 = nullptr);
    static int32_t sprint(char* str, char fmt, _d_real x);
    static _d_real zero;
    static _d_real one;
    static _d_real minusone;
    static _d_real half;
    static void initialize();
    CTFloat()
    {
    }
};

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