text: // 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;
  struct Scope;
  class DeprecatedDeclaration;
  class UserAttributeDeclaration;
  class UnitTestDeclaration;
  class Module;
  class TemplateInstance;
  class LabelDsymbol;
  class ClassDeclaration;
  class Type;
  class Package;
  class EnumMember;
  class TemplateDeclaration;
  class TemplateMixin;
  class ForwardingAttribDeclaration;
  class Nspace;
  class Declaration;
  class StorageClassDeclaration;
  class ExpressionDsymbol;
  class AliasAssign;
  class ThisDeclaration;
  class TypeInfoDeclaration;
  class TupleDeclaration;
  class AliasDeclaration;
  class FuncDeclaration;
  class FuncAliasDeclaration;
  class OverDeclaration;
  class FuncLiteralDeclaration;
  class CtorDeclaration;
  class PostBlitDeclaration;
  class DtorDeclaration;
  class StaticCtorDeclaration;
  class StaticDtorDeclaration;
  class SharedStaticCtorDeclaration;
  class SharedStaticDtorDeclaration;
  class InvariantDeclaration;
  class NewDeclaration;
  class VarDeclaration;
  class VersionSymbol;
  class DebugSymbol;
  class StructDeclaration;
  class UnionDeclaration;
  class InterfaceDeclaration;
  class ForwardingScopeDsymbol;
  class WithScopeSymbol;
  class ArrayScopeSymbol;
  class Import;
  class EnumDeclaration;
  class SymbolDeclaration;
  class AttribDeclaration;
  class AnonDeclaration;
  class VisibilityDeclaration;
  class OverloadSet;
  class CompileDeclaration;
  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 TupleExp;
  class IntegerExp;
  class ErrorExp;
  class VoidInitExp;
  class RealExp;
  class ComplexExp;
  class IdentifierExp;
  class DollarExp;
  class DsymbolExp;
  class ThisExp;
  class SuperExp;
  class NullExp;
  class ArrayLiteralExp;
  class AssocArrayLiteralExp;
  class StructLiteralExp;
  class 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 DotIdExp;
  class DotTemplateExp;
  class DotVarExp;
  class DotTemplateInstanceExp;
  class DelegateExp;
  class DotTypeExp;
  class CallExp;
  class AddrExp;
  class PtrExp;
  class NegExp;
  class UAddExp;
  class ComExp;
  class NotExp;
  class DeleteExp;
  class CastExp;
  class VectorExp;
  class VectorArrayExp;
  class SliceExp;
  class ArrayLengthExp;
  class ArrayExp;
  class DotExp;
  class CommaExp;
  class IntervalExp;
  class DelegatePtrExp;
  class DelegateFuncptrExp;
  class IndexExp;
  class PostExp;
  class PreExp;
  class AssignExp;
  class ConstructExp;
  class BlitExp;
  class AddAssignExp;
  class MinAssignExp;
  class MulAssignExp;
  class DivAssignExp;
  class ModAssignExp;
  class AndAssignExp;
  class OrAssignExp;
  class XorAssignExp;
  class PowAssignExp;
  class ShlAssignExp;
  class ShrAssignExp;
  class UshrAssignExp;
  class CatAssignExp;
  class CatElemAssignExp;
  class CatDcharAssignExp;
  class AddExp;
  class MinExp;
  class CatExp;
  class MulExp;
  class DivExp;
  class ModExp;
  class PowExp;
  class ShlExp;
  class ShrExp;
  class UshrExp;
  class AndExp;
  class OrExp;
  class XorExp;
  class LogicalExp;
  class InExp;
  class RemoveExp;
  class EqualExp;
  class IdentityExp;
  class CondExp;
  class DefaultInitExp;
  class FileInitExp;
  class LineInitExp;
  class ModuleInitExp;
  class FuncInitExp;
  class PrettyFuncInitExp;
  class ThrownExceptionExp;
  class BinAssignExp;
  class TypeInfoClassDeclaration;
  class TypeFunction;
  class Initializer;
  struct IntRange;
  struct Macro;
  struct ModuleDeclaration;
  struct FileBuffer;
  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 ErrorInitializer;
  class VoidInitializer;
  class StructInitializer;
  class ExpInitializer;
  class CInitializer;
  class ErrorStatement;
  class ExpStatement;
  class CompoundStatement;
  class IfStatement;
  class ConditionalStatement;
  class StaticForeachStatement;
  class DefaultStatement;
  class LabelStatement;
  class GotoDefaultStatement;
  class BreakStatement;
  class DtorExpStatement;
  class CompileStatement;
  class ForwardingStatement;
  class DoStatement;
  class WhileStatement;
  class ForStatement;
  class SwitchStatement;
  class ContinueStatement;
  class TryCatchStatement;
  class ThrowStatement;
  class DebugStatement;
  class TryFinallyStatement;
  class ScopeGuardStatement;
  class SwitchErrorStatement;
  class UnrolledLoopStatement;
  class CompoundDeclarationStatement;
  struct Token;
  struct code;
  class StaticAssert;
  struct Triple;
  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
  {
      // Ignoring var length alignment 0
      size_t length;
      // Ignoring var data alignment 0
      _d_dynamicArray< T > data;
      // Ignoring var SMALLARRAYCAP alignment 0
      enum : int32_t { SMALLARRAYCAP = 1 };
  
      // Ignoring var smallarray alignment 0
      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();
      typedef length opDollar;
      typedef length dim;
      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;
      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;
      bool rvalueRefParam;
      CppStdRevision cplusplus;
      bool markdown;
      bool vmarkdown;
      bool showGaggedErrors;
      bool printErrorContext;
      bool manual;
      bool usage;
      bool mcpuUsage;
      bool transitionUsage;
      bool checkUsage;
      bool checkActionUsage;
      bool revertUsage;
      bool previewUsage;
      bool externStdUsage;
      bool hcUsage;
      bool logo;
      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();
      Param() :
          obj(true),
          link(true),
          dll(),
          lib(),
          multiobj(),
          oneobj(),
          trace(),
          tracegc(),
          verbose(),
          vcg_ast(),
          showColumns(),
          vtls(),
          vtemplates(),
          vtemplatesListInstances(),
          vgc(),
          vfield(),
          vcomplex(true),
          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(),
          fixAliasThis(),
          inclusiveInContracts(),
          ehnogc(),
          fieldwise(),
          rvalueRefParam(),
          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, 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 = false, bool fixAliasThis = false, bool inclusiveInContracts = false, bool ehnogc = false, FeatureState dtorFields = (FeatureState)-1, bool fieldwise = false, bool rvalueRefParam = false, 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* >(0LLU, {}, arrayliteral), 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* >(0LLU, {}, arrayliteral), 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* >(0LLU, {}, arrayliteral), MessageStyle messageStyle = (MessageStyle)0u, bool run = false, Array<const char* > runargs = Array<const char* >(0LLU, {}, arrayliteral), Array<const char* > objfiles = Array<const char* >(0LLU, {}, arrayliteral), Array<const char* > linkswitches = Array<const char* >(0LLU, {}, arrayliteral), Array<bool > linkswitchIsForCC = Array<bool >(0LLU, {}, arrayliteral), Array<const char* > libfiles = Array<const char* >(0LLU, {}, arrayliteral), Array<const char* > dllfiles = Array<const char* >(0LLU, {}, arrayliteral), _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),
          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;
      enum : int32_t { recursionLimit = 500 };
  
      uint32_t startGagging();
      bool endGagging(uint32_t oldGagged);
      void increaseErrorCount();
      void _init();
      uint32_t versionNumber();
      const char* const versionChars();
      ~Global();
      Global() :
          inifilename(),
          copyright(73, "Copyright (C) 1999-2021 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()
      {
      }
      Global(_d_dynamicArray< const char > inifilename, _d_dynamicArray< const char > copyright = { 73, "Copyright (C) 1999-2021 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(true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, 0u, false, false, (DiagnosticReporting)1u, false, false, false, (FeatureState)-1, (FeatureState)-1, false, false, false, (DiagnosticReporting)2u, (PIC)0u, false, false, 0u, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, (FeatureState)-1, false, false, (CppStdRevision)201103u, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKENABLE)0u, (CHECKACTION)0u, 20u, {}, Array<const char* >(0LLU, {}, arrayliteral), nullptr, nullptr, {}, {}, {}, false, {}, {}, Array<const char* >(0LLU, {}, arrayliteral), false, {}, {}, true, (CxxHeaderMode)0u, {}, {}, false, {}, (JsonFieldFlags)0u, nullptr, nullptr, 0, 0u, nullptr, 0u, nullptr, {}, {}, {}, {}, nullptr, false, {}, Array<const char* >(0LLU, {}, arrayliteral), (MessageStyle)0u, false, Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<bool >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), Array<const char* >(0LLU, {}, arrayliteral), {}, {}, {}, {}), 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) :
          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)
          {}
  };
  
  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
  {
      init = 0,
      semantic = 1,
      semanticdone = 2,
      semantic2 = 3,
      semantic2done = 4,
      semantic3 = 5,
      semantic3done = 6,
      inline_ = 7,
      inlinedone = 8,
      obj = 9,
  };
  
  struct Ungag final
  {
      uint32_t oldgag;
      ~Ungag();
      Ungag() :
          oldgag()
      {
      }
  };
  
  typedef uint64_t d_uns64;
  
  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;
      Symbol* isym;
      const char* comment;
      const Loc loc;
      Scope* _scope;
      const char* prettystring;
      bool errors;
      PASS semanticRun;
      uint16_t localNum;
      DeprecatedDeclaration* depdecl;
      UserAttributeDeclaration* userAttribDecl;
      UnitTestDeclaration* ddocUnittest;
      static Dsymbol* create(Identifier* ident);
      const char* toChars() const;
      virtual const char* toPrettyCharsHelper();
      const Loc getLoc();
      const char* locToChars();
      bool equals(const RootObject* const o) const;
      bool isAnonymous() const;
      void error(const Loc& loc, const char* format, ...);
      void error(const char* format, ...);
      void deprecation(const Loc& loc, const char* format, ...);
      void deprecation(const char* format, ...);
      bool checkDeprecated(const Loc& loc, Scope* sc);
      Module* getModule();
      Module* getAccessModule();
      Dsymbol* pastMixin();
      Dsymbol* toParent();
      Dsymbol* toParent2();
      Dsymbol* toParentDecl();
      Dsymbol* toParentLocal();
      Dsymbol* toParentP(Dsymbol* p1, Dsymbol* p2 = nullptr);
      TemplateInstance* isInstantiated();
      bool followInstantiationContext(Dsymbol* p1, Dsymbol* p2 = nullptr);
      TemplateInstance* isSpeculative();
      Ungag ungagSpeculative() const;
      DYNCAST dyncast() const;
      virtual Identifier* getIdent();
      virtual const char* toPrettyChars(bool QualifyTypes = false);
      virtual const char* kind() const;
      virtual Dsymbol* toAlias();
      virtual Dsymbol* toAlias2();
      virtual void addMember(Scope* sc, ScopeDsymbol* sds);
      virtual void setScope(Scope* sc);
      virtual void importAll(Scope* sc);
      virtual Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 0);
      virtual bool overloadInsert(Dsymbol* s);
      virtual d_uns64 size(const Loc& loc);
      virtual bool isforwardRef();
      virtual AggregateDeclaration* isThis();
      virtual bool isExport() const;
      virtual bool isImportedSymbol() const;
      virtual bool isDeprecated() const;
      virtual bool isOverloadable() const;
      virtual LabelDsymbol* isLabel();
      AggregateDeclaration* isMember();
      AggregateDeclaration* isMember2();
      AggregateDeclaration* isMemberDecl();
      AggregateDeclaration* isMemberLocal();
      ClassDeclaration* isClassMember();
      virtual Type* getType();
      virtual bool needThis();
      virtual Visibility visible();
      virtual Dsymbol* syntaxCopy(Dsymbol* s);
      virtual bool oneMember(Dsymbol** ps, Identifier* ident);
      virtual void setFieldOffset(AggregateDeclaration* ad, uint32_t* poffset, bool isunion);
      virtual bool hasPointers();
      virtual bool hasStaticCtorOrDtor();
      virtual void addLocalClass(Array<ClassDeclaration* >* _param_0);
      virtual void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories);
      virtual void checkCtorConstInit();
      virtual void addComment(const char* comment);
      bool inNonRoot();
      void accept(Visitor* v);
      virtual Package* isPackage();
      virtual Module* isModule();
      virtual EnumMember* isEnumMember();
      virtual TemplateDeclaration* isTemplateDeclaration();
      virtual TemplateInstance* isTemplateInstance();
      virtual TemplateMixin* isTemplateMixin();
      virtual ForwardingAttribDeclaration* isForwardingAttribDeclaration();
      virtual Nspace* isNspace();
      virtual Declaration* isDeclaration();
      virtual StorageClassDeclaration* isStorageClassDeclaration();
      virtual ExpressionDsymbol* isExpressionDsymbol();
      virtual AliasAssign* isAliasAssign();
      virtual ThisDeclaration* isThisDeclaration();
      virtual TypeInfoDeclaration* isTypeInfoDeclaration();
      virtual TupleDeclaration* isTupleDeclaration();
      virtual AliasDeclaration* isAliasDeclaration();
      virtual AggregateDeclaration* isAggregateDeclaration();
      virtual FuncDeclaration* isFuncDeclaration();
      virtual FuncAliasDeclaration* isFuncAliasDeclaration();
      virtual OverDeclaration* isOverDeclaration();
      virtual FuncLiteralDeclaration* isFuncLiteralDeclaration();
      virtual CtorDeclaration* isCtorDeclaration();
      virtual PostBlitDeclaration* isPostBlitDeclaration();
      virtual DtorDeclaration* isDtorDeclaration();
      virtual StaticCtorDeclaration* isStaticCtorDeclaration();
      virtual StaticDtorDeclaration* isStaticDtorDeclaration();
      virtual SharedStaticCtorDeclaration* isSharedStaticCtorDeclaration();
      virtual SharedStaticDtorDeclaration* isSharedStaticDtorDeclaration();
      virtual InvariantDeclaration* isInvariantDeclaration();
      virtual UnitTestDeclaration* isUnitTestDeclaration();
      virtual NewDeclaration* isNewDeclaration();
      virtual VarDeclaration* isVarDeclaration();
      virtual VersionSymbol* isVersionSymbol();
      virtual DebugSymbol* isDebugSymbol();
      virtual ClassDeclaration* isClassDeclaration();
      virtual StructDeclaration* isStructDeclaration();
      virtual UnionDeclaration* isUnionDeclaration();
      virtual InterfaceDeclaration* isInterfaceDeclaration();
      virtual ScopeDsymbol* isScopeDsymbol();
      virtual ForwardingScopeDsymbol* isForwardingScopeDsymbol();
      virtual WithScopeSymbol* isWithScopeSymbol();
      virtual ArrayScopeSymbol* isArrayScopeSymbol();
      virtual Import* isImport();
      virtual EnumDeclaration* isEnumDeclaration();
      virtual SymbolDeclaration* isSymbolDeclaration();
      virtual AttribDeclaration* isAttribDeclaration();
      virtual AnonDeclaration* isAnonDeclaration();
      virtual CPPNamespaceDeclaration* isCPPNamespaceDeclaration();
      virtual VisibilityDeclaration* isVisibilityDeclaration();
      virtual OverloadSet* isOverloadSet();
      virtual CompileDeclaration* isCompileDeclaration();
  };
  
  struct BitArray final
  {
      typedef uint64_t Chunk_t;
      enum : uint64_t { ChunkSize = 8LLU };
  
      enum : uint64_t { BitsPerChunk = 64LLU };
  
  private:
      size_t len;
      uint64_t* ptr;
  public:
      BitArray()
      {
      }
  };
  
  class ScopeDsymbol : public Dsymbol
  {
  public:
      Array<Dsymbol* >* members;
      DsymbolTable* symtab;
      uint32_t endlinnum;
  private:
      Array<Dsymbol* >* importedScopes;
      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);
      ~ScopeDsymbol();
  };
  
  typedef uint64_t StorageClass;
  
  enum class ClassKind : uint8_t
  {
      d = 0u,
      cpp = 1u,
      objc = 2u,
  };
  
  enum class CPPMANGLE : uint8_t
  {
      def = 0u,
      asStruct = 1u,
      asClass = 2u,
  };
  
  enum class Sizeok : uint8_t
  {
      none = 0u,
      fwd = 1u,
      inProcess = 2u,
      done = 3u,
  };
  
  enum class LINK : uint8_t
  {
      default_ = 0u,
      d = 1u,
      c = 2u,
      cpp = 3u,
      windows = 4u,
      objc = 5u,
      system = 6u,
  };
  
  enum class 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 Include : uint8_t
  {
      notComputed = 0u,
      yes = 1u,
      no = 2u,
  };
  
  enum class TOK : uint16_t
  {
      reserved = 0u,
      leftParenthesis = 1u,
      rightParenthesis = 2u,
      leftBracket = 3u,
      rightBracket = 4u,
      leftCurly = 5u,
      rightCurly = 6u,
      colon = 7u,
      negate = 8u,
      semicolon = 9u,
      dotDotDot = 10u,
      endOfFile = 11u,
      cast_ = 12u,
      null_ = 13u,
      assert_ = 14u,
      true_ = 15u,
      false_ = 16u,
      array = 17u,
      call = 18u,
      address = 19u,
      type = 20u,
      throw_ = 21u,
      new_ = 22u,
      delete_ = 23u,
      star = 24u,
      symbolOffset = 25u,
      variable = 26u,
      dotVariable = 27u,
      dotIdentifier = 28u,
      dotTemplateInstance = 29u,
      dotType = 30u,
      slice = 31u,
      arrayLength = 32u,
      version_ = 33u,
      module_ = 34u,
      dollar = 35u,
      template_ = 36u,
      dotTemplateDeclaration = 37u,
      declaration = 38u,
      typeof_ = 39u,
      pragma_ = 40u,
      dSymbol = 41u,
      typeid_ = 42u,
      uadd = 43u,
      remove = 44u,
      newAnonymousClass = 45u,
      comment = 46u,
      arrayLiteral = 47u,
      assocArrayLiteral = 48u,
      structLiteral = 49u,
      classReference = 50u,
      thrownException = 51u,
      delegatePointer = 52u,
      delegateFunctionPointer = 53u,
      lessThan = 54u,
      greaterThan = 55u,
      lessOrEqual = 56u,
      greaterOrEqual = 57u,
      equal = 58u,
      notEqual = 59u,
      identity = 60u,
      notIdentity = 61u,
      index = 62u,
      is_ = 63u,
      leftShift = 64u,
      rightShift = 65u,
      leftShiftAssign = 66u,
      rightShiftAssign = 67u,
      unsignedRightShift = 68u,
      unsignedRightShiftAssign = 69u,
      concatenate = 70u,
      concatenateAssign = 71u,
      concatenateElemAssign = 72u,
      concatenateDcharAssign = 73u,
      add = 74u,
      min = 75u,
      addAssign = 76u,
      minAssign = 77u,
      mul = 78u,
      div = 79u,
      mod = 80u,
      mulAssign = 81u,
      divAssign = 82u,
      modAssign = 83u,
      and_ = 84u,
      or_ = 85u,
      xor_ = 86u,
      andAssign = 87u,
      orAssign = 88u,
      xorAssign = 89u,
      assign = 90u,
      not_ = 91u,
      tilde = 92u,
      plusPlus = 93u,
      minusMinus = 94u,
      construct = 95u,
      blit = 96u,
      dot = 97u,
      comma = 98u,
      question = 99u,
      andAnd = 100u,
      orOr = 101u,
      prePlusPlus = 102u,
      preMinusMinus = 103u,
      int32Literal = 104u,
      uns32Literal = 105u,
      int64Literal = 106u,
      uns64Literal = 107u,
      int128Literal = 108u,
      uns128Literal = 109u,
      float32Literal = 110u,
      float64Literal = 111u,
      float80Literal = 112u,
      imaginary32Literal = 113u,
      imaginary64Literal = 114u,
      imaginary80Literal = 115u,
      charLiteral = 116u,
      wcharLiteral = 117u,
      dcharLiteral = 118u,
      identifier = 119u,
      string_ = 120u,
      hexadecimalString = 121u,
      this_ = 122u,
      super_ = 123u,
      halt = 124u,
      tuple = 125u,
      error = 126u,
      void_ = 127u,
      int8 = 128u,
      uns8 = 129u,
      int16 = 130u,
      uns16 = 131u,
      int32 = 132u,
      uns32 = 133u,
      int64 = 134u,
      uns64 = 135u,
      int128 = 136u,
      uns128 = 137u,
      float32 = 138u,
      float64 = 139u,
      float80 = 140u,
      imaginary32 = 141u,
      imaginary64 = 142u,
      imaginary80 = 143u,
      complex32 = 144u,
      complex64 = 145u,
      complex80 = 146u,
      char_ = 147u,
      wchar_ = 148u,
      dchar_ = 149u,
      bool_ = 150u,
      struct_ = 151u,
      class_ = 152u,
      interface_ = 153u,
      union_ = 154u,
      enum_ = 155u,
      import_ = 156u,
      alias_ = 157u,
      override_ = 158u,
      delegate_ = 159u,
      function_ = 160u,
      mixin_ = 161u,
      align_ = 162u,
      extern_ = 163u,
      private_ = 164u,
      protected_ = 165u,
      public_ = 166u,
      export_ = 167u,
      static_ = 168u,
      final_ = 169u,
      const_ = 170u,
      abstract_ = 171u,
      debug_ = 172u,
      deprecated_ = 173u,
      in_ = 174u,
      out_ = 175u,
      inout_ = 176u,
      lazy_ = 177u,
      auto_ = 178u,
      package_ = 179u,
      immutable_ = 180u,
      if_ = 181u,
      else_ = 182u,
      while_ = 183u,
      for_ = 184u,
      do_ = 185u,
      switch_ = 186u,
      case_ = 187u,
      default_ = 188u,
      break_ = 189u,
      continue_ = 190u,
      with_ = 191u,
      synchronized_ = 192u,
      return_ = 193u,
      goto_ = 194u,
      try_ = 195u,
      catch_ = 196u,
      finally_ = 197u,
      asm_ = 198u,
      foreach_ = 199u,
      foreach_reverse_ = 200u,
      scope_ = 201u,
      onScopeExit = 202u,
      onScopeFailure = 203u,
      onScopeSuccess = 204u,
      invariant_ = 205u,
      unittest_ = 206u,
      argumentTypes = 207u,
      ref_ = 208u,
      macro_ = 209u,
      parameters = 210u,
      traits = 211u,
      overloadSet = 212u,
      pure_ = 213u,
      nothrow_ = 214u,
      gshared = 215u,
      line = 216u,
      file = 217u,
      fileFullPath = 218u,
      moduleString = 219u,
      functionString = 220u,
      prettyFunction = 221u,
      shared_ = 222u,
      at = 223u,
      pow = 224u,
      powAssign = 225u,
      goesTo = 226u,
      vector = 227u,
      pound = 228u,
      interval = 229u,
      voidExpression = 230u,
      cantExpression = 231u,
      showCtfeContext = 232u,
      objcClassReference = 233u,
      vectorArray = 234u,
      arrow = 235u,
      colonColon = 236u,
      wchar_tLiteral = 237u,
      compoundLiteral = 238u,
      inline_ = 239u,
      register_ = 240u,
      restrict = 241u,
      signed_ = 242u,
      sizeof_ = 243u,
      typedef_ = 244u,
      unsigned_ = 245u,
      volatile_ = 246u,
      _Alignas = 247u,
      _Alignof = 248u,
      _Atomic = 249u,
      _Bool = 250u,
      _Complex_ = 251u,
      _Generic = 252u,
      _Imaginary = 253u,
      _Noreturn = 254u,
      _Static_assert = 255u,
      _Thread_local = 256u,
      __cdecl_ = 257u,
      __declspec_ = 258u,
      __attribute___ = 259u,
  };
  
  typedef uint64_t dinteger_t;
  
  typedef uint64_t uinteger_t;
  
  enum class MATCH
  {
      nomatch = 0,
      convert = 1,
      constant = 2,
      exact = 3,
  };
  
  enum class Modifiable
  {
      no = 0,
      yes = 1,
      initialization = 2,
  };
  
  class Expression : public ASTNode
  {
  public:
      const TOK op;
      uint8_t size;
      uint8_t parens;
      Type* type;
      Loc loc;
      static void _init();
      static void deinitialize();
      Expression* copy();
      virtual Expression* syntaxCopy();
      DYNCAST dyncast() const;
      const char* toChars() const;
      void error(const char* format, ...) const;
      void errorSupplemental(const char* format, ...);
      void warning(const char* format, ...) const;
      void deprecation(const char* format, ...) const;
      virtual dinteger_t toInteger();
      virtual uinteger_t toUInteger();
      virtual _d_real toReal();
      virtual _d_real toImaginary();
      virtual complex_t toComplex();
      virtual StringExp* toStringExp();
      virtual TupleExp* toTupleExp();
      virtual bool isLvalue();
      virtual Expression* toLvalue(Scope* sc, Expression* e);
      virtual Expression* modifiableLvalue(Scope* sc, Expression* e);
      Expression* implicitCastTo(Scope* sc, Type* t);
      MATCH implicitConvTo(Type* t);
      Expression* castTo(Scope* sc, Type* t);
      virtual Expression* resolveLoc(const Loc& loc, Scope* sc);
      virtual bool checkType();
      virtual bool checkValue();
      bool checkDeprecated(Scope* sc, Dsymbol* s);
      virtual Modifiable checkModifiable(Scope* sc, int32_t flag = 0);
      virtual Expression* addDtorHook(Scope* sc);
      Expression* addressOf();
      Expression* deref();
      Expression* optimize(int32_t result, bool keepLvalue = false);
      Expression* ctfeInterpret();
      int32_t isConst();
      virtual bool isBool(bool result);
      virtual bool hasCode();
      IntegerExp* isIntegerExp();
      ErrorExp* isErrorExp();
      VoidInitExp* isVoidInitExp();
      RealExp* isRealExp();
      ComplexExp* isComplexExp();
      IdentifierExp* isIdentifierExp();
      DollarExp* isDollarExp();
      DsymbolExp* isDsymbolExp();
      ThisExp* isThisExp();
      SuperExp* isSuperExp();
      NullExp* isNullExp();
      StringExp* isStringExp();
      TupleExp* isTupleExp();
      ArrayLiteralExp* isArrayLiteralExp();
      AssocArrayLiteralExp* isAssocArrayLiteralExp();
      StructLiteralExp* isStructLiteralExp();
      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();
      DotIdExp* isDotIdExp();
      DotTemplateExp* isDotTemplateExp();
      DotVarExp* isDotVarExp();
      DotTemplateInstanceExp* isDotTemplateInstanceExp();
      DelegateExp* isDelegateExp();
      DotTypeExp* isDotTypeExp();
      CallExp* isCallExp();
      AddrExp* isAddrExp();
      PtrExp* isPtrExp();
      NegExp* isNegExp();
      UAddExp* isUAddExp();
      ComExp* isComExp();
      NotExp* isNotExp();
      DeleteExp* isDeleteExp();
      CastExp* isCastExp();
      VectorExp* isVectorExp();
      VectorArrayExp* isVectorArrayExp();
      SliceExp* isSliceExp();
      ArrayLengthExp* isArrayLengthExp();
      ArrayExp* isArrayExp();
      DotExp* isDotExp();
      CommaExp* isCommaExp();
      IntervalExp* isIntervalExp();
      DelegatePtrExp* isDelegatePtrExp();
      DelegateFuncptrExp* isDelegateFuncptrExp();
      IndexExp* isIndexExp();
      PostExp* isPostExp();
      PreExp* isPreExp();
      AssignExp* isAssignExp();
      ConstructExp* isConstructExp();
      BlitExp* isBlitExp();
      AddAssignExp* isAddAssignExp();
      MinAssignExp* isMinAssignExp();
      MulAssignExp* isMulAssignExp();
      DivAssignExp* isDivAssignExp();
      ModAssignExp* isModAssignExp();
      AndAssignExp* isAndAssignExp();
      OrAssignExp* isOrAssignExp();
      XorAssignExp* isXorAssignExp();
      PowAssignExp* isPowAssignExp();
      ShlAssignExp* isShlAssignExp();
      ShrAssignExp* isShrAssignExp();
      UshrAssignExp* isUshrAssignExp();
      CatAssignExp* isCatAssignExp();
      CatElemAssignExp* isCatElemAssignExp();
      CatDcharAssignExp* isCatDcharAssignExp();
      AddExp* isAddExp();
      MinExp* isMinExp();
      CatExp* isCatExp();
      MulExp* isMulExp();
      DivExp* isDivExp();
      ModExp* isModExp();
      PowExp* isPowExp();
      ShlExp* isShlExp();
      ShrExp* isShrExp();
      UshrExp* isUshrExp();
      AndExp* isAndExp();
      OrExp* isOrExp();
      XorExp* isXorExp();
      LogicalExp* isLogicalExp();
      InExp* isInExp();
      RemoveExp* isRemoveExp();
      EqualExp* isEqualExp();
      IdentityExp* isIdentityExp();
      CondExp* isCondExp();
      DefaultInitExp* isDefaultInitExp();
      FileInitExp* isFileInitExp();
      LineInitExp* isLineInitExp();
      ModuleInitExp* isModuleInitExp();
      FuncInitExp* isFuncInitExp();
      PrettyFuncInitExp* isPrettyFuncInitExp();
      ClassReferenceExp* isClassReferenceExp();
      ThrownExceptionExp* isThrownExceptionExp();
      virtual BinAssignExp* isBinAssignExp();
      void accept(Visitor* v);
  };
  
  enum class Abstract : uint8_t
  {
      fwdref = 0u,
      yes = 1u,
      no = 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()
      {
      }
  };
  
  struct FileBuffer final
  {
      _d_dynamicArray< uint8_t > data;
      static FileBuffer* create();
      FileBuffer() :
          data()
      {
      }
      FileBuffer(_d_dynamicArray< uint8_t > data) :
          data(data)
          {}
  };
  
  struct File final
  {
      struct ReadResult final
      {
          bool success;
          FileBuffer buffer;
          ReadResult() :
              success(),
              buffer()
          {
          }
          ReadResult(bool success, FileBuffer buffer = FileBuffer({})) :
              success(success),
              buffer(buffer)
              {}
      };
  
      static ReadResult read(const char* name);
      static bool write(const char* name, const void* data, size_t size);
      static void remove(const char* name);
      static bool update(const char* name, const void* data, size_t size);
      File()
      {
      }
  };
  
  enum class StructPOD
  {
      no = 0,
      yes = 1,
      fwd = 2,
  };
  
  template <typename K, typename V>
  struct AssocArray final
  {
      // Ignoring var aa alignment 0
      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,
  };
  
  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;
      int32_t covariant(Type* t, uint64_t* pstc = nullptr);
      const char* toChars() const;
      char* toPrettyChars(bool QualifyTypes = false);
      static void _init();
      static void deinitialize();
      d_uns64 size();
      virtual d_uns64 size(const Loc& loc);
      virtual uint32_t alignsize();
      Type* trySemantic(const Loc& loc, Scope* sc);
      Type* merge2();
      void modToBuffer(OutBuffer* buf) const;
      char* modToChars() const;
      virtual bool isintegral();
      virtual bool isfloating();
      virtual bool isreal();
      virtual bool isimaginary();
      virtual bool iscomplex();
      virtual bool isscalar();
      virtual bool isunsigned();
      virtual bool isscope();
      virtual bool isString();
      virtual bool isAssignable();
      virtual bool isBoolean();
      virtual void checkDeprecated(const Loc& loc, Scope* sc);
      bool isConst() const;
      bool isImmutable() const;
      bool isMutable() const;
      bool isShared() const;
      bool isSharedConst() const;
      bool isWild() const;
      bool isWildConst() const;
      bool isSharedWild() const;
      bool isNaked() const;
      Type* nullAttributes() const;
      Type* constOf();
      Type* immutableOf();
      Type* mutableOf();
      Type* sharedOf();
      Type* sharedConstOf();
      Type* unSharedOf();
      Type* wildOf();
      Type* wildConstOf();
      Type* sharedWildOf();
      Type* sharedWildConstOf();
      void fixTo(Type* t);
      void check();
      Type* addSTC(StorageClass stc);
      Type* castMod(uint8_t mod);
      Type* addMod(uint8_t mod);
      virtual Type* addStorageClass(StorageClass stc);
      Type* pointerTo();
      Type* referenceTo();
      Type* arrayOf();
      Type* sarrayOf(dinteger_t dim);
      bool hasDeprecatedAliasThis();
      Type* aliasthisOf();
      virtual Type* makeConst();
      virtual Type* makeImmutable();
      virtual Type* makeShared();
      virtual Type* makeSharedConst();
      virtual Type* makeWild();
      virtual Type* makeWildConst();
      virtual Type* makeSharedWild();
      virtual Type* makeSharedWildConst();
      virtual Type* makeMutable();
      virtual Dsymbol* toDsymbol(Scope* sc);
      Type* toBasetype();
      virtual bool isBaseOf(Type* t, int32_t* poffset);
      virtual MATCH implicitConvTo(Type* to);
      virtual MATCH constConv(Type* to);
      virtual uint8_t deduceWild(Type* t, bool isRef);
      virtual Type* substWildTo(uint32_t mod);
      Type* unqualify(uint32_t m);
      virtual Type* toHeadMutable();
      virtual ClassDeclaration* isClassHandle();
      virtual uint32_t alignment();
      virtual Expression* defaultInitLiteral(const Loc& loc);
      virtual bool isZeroInit(const Loc& loc);
      Identifier* getTypeInfoIdent();
      virtual int32_t hasWild() const;
      virtual bool hasPointers();
      virtual bool hasVoidInitPointers();
      virtual 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 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::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::VarExp e);
      virtual void visit(typename AST::DollarExp e);
      virtual void visit(typename AST::SuperExp e);
      virtual void visit(typename AST::AddrExp e);
      virtual void visit(typename AST::PreExp e);
      virtual void visit(typename AST::PtrExp e);
      virtual void visit(typename AST::NegExp e);
      virtual void visit(typename AST::UAddExp e);
      virtual void visit(typename AST::NotExp e);
      virtual void visit(typename AST::ComExp e);
      virtual void visit(typename AST::DeleteExp e);
      virtual void visit(typename AST::CastExp e);
      virtual void visit(typename AST::CallExp e);
      virtual void visit(typename AST::DotIdExp e);
      virtual void visit(typename AST::AssertExp e);
      virtual void visit(typename AST::ImportExp e);
      virtual void visit(typename AST::DotTemplateInstanceExp e);
      virtual void visit(typename AST::ArrayExp e);
      virtual void visit(typename AST::FuncInitExp e);
      virtual void visit(typename AST::PrettyFuncInitExp e);
      virtual void visit(typename AST::FileInitExp e);
      virtual void visit(typename AST::LineInitExp e);
      virtual void visit(typename AST::ModuleInitExp e);
      virtual void visit(typename AST::CommaExp e);
      virtual void visit(typename AST::PostExp e);
      virtual void visit(typename AST::PowExp e);
      virtual void visit(typename AST::MulExp e);
      virtual void visit(typename AST::DivExp e);
      virtual void visit(typename AST::ModExp e);
      virtual void visit(typename AST::AddExp e);
      virtual void visit(typename AST::MinExp e);
      virtual void visit(typename AST::CatExp e);
      virtual void visit(typename AST::ShlExp e);
      virtual void visit(typename AST::ShrExp e);
      virtual void visit(typename AST::UshrExp e);
      virtual void visit(typename AST::EqualExp e);
      virtual void visit(typename AST::InExp e);
      virtual void visit(typename AST::IdentityExp e);
      virtual void visit(typename AST::CmpExp e);
      virtual void visit(typename AST::AndExp e);
      virtual void visit(typename AST::XorExp e);
      virtual void visit(typename AST::OrExp e);
      virtual void visit(typename AST::LogicalExp e);
      virtual void visit(typename AST::CondExp e);
      virtual void visit(typename AST::AssignExp e);
      virtual void visit(typename AST::BinAssignExp e);
      virtual void visit(typename AST::AddAssignExp e);
      virtual void visit(typename AST::MinAssignExp e);
      virtual void visit(typename AST::MulAssignExp e);
      virtual void visit(typename AST::DivAssignExp e);
      virtual void visit(typename AST::ModAssignExp e);
      virtual void visit(typename AST::PowAssignExp e);
      virtual void visit(typename AST::AndAssignExp e);
      virtual void visit(typename AST::OrAssignExp e);
      virtual void visit(typename AST::XorAssignExp e);
      virtual void visit(typename AST::ShlAssignExp e);
      virtual void visit(typename AST::ShrAssignExp e);
      virtual void visit(typename AST::UshrAssignExp e);
      virtual void visit(typename AST::CatAssignExp e);
      virtual void visit(typename AST::TemplateAliasParameter tp);
      virtual void visit(typename AST::TemplateTypeParameter tp);
      virtual void visit(typename AST::TemplateTupleParameter tp);
      virtual void visit(typename AST::TemplateValueParameter tp);
      virtual void visit(typename AST::TemplateThisParameter tp);
      virtual void visit(typename AST::StaticIfCondition c);
      virtual void visit(typename AST::DVCondition c);
      virtual void visit(typename AST::DebugCondition c);
      virtual void visit(typename AST::VersionCondition c);
      virtual void visit(typename AST::ExpInitializer i);
      virtual void visit(typename AST::StructInitializer i);
      virtual void visit(typename AST::ArrayInitializer i);
      virtual void visit(typename AST::VoidInitializer i);
      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 STC : uint64_t
  {
      undefined_ = 0LLU,
      static_ = 1LLU,
      extern_ = 2LLU,
      const_ = 4LLU,
      final_ = 8LLU,
      abstract_ = 16LLU,
      parameter = 32LLU,
      field = 64LLU,
      override_ = 128LLU,
      auto_ = 256LLU,
      synchronized_ = 512LLU,
      deprecated_ = 1024LLU,
      in_ = 2048LLU,
      out_ = 4096LLU,
      lazy_ = 8192LLU,
      foreach_ = 16384LLU,
      variadic = 65536LLU,
      ctorinit = 131072LLU,
      templateparameter = 262144LLU,
      scope_ = 524288LLU,
      immutable_ = 1048576LLU,
      ref_ = 2097152LLU,
      init = 4194304LLU,
      manifest = 8388608LLU,
      nodtor = 16777216LLU,
      nothrow_ = 33554432LLU,
      pure_ = 67108864LLU,
      tls = 134217728LLU,
      alias_ = 268435456LLU,
      shared_ = 536870912LLU,
      gshared = 1073741824LLU,
      wild = 2147483648LLU,
      property = 4294967296LLU,
      safe = 8589934592LLU,
      trusted = 17179869184LLU,
      system = 34359738368LLU,
      ctfe = 68719476736LLU,
      disable = 137438953472LLU,
      result = 274877906944LLU,
      nodefaultctor = 549755813888LLU,
      temp = 1099511627776LLU,
      rvalue = 2199023255552LLU,
      nogc = 4398046511104LLU,
      volatile_ = 8796093022208LLU,
      return_ = 17592186044416LLU,
      autoref = 35184372088832LLU,
      inference = 70368744177664LLU,
      exptemp = 140737488355328LLU,
      maybescope = 281474976710656LLU,
      scopeinferred = 562949953421312LLU,
      future = 1125899906842624LLU,
      local = 2251799813685248LLU,
      returninferred = 4503599627370496LLU,
      live = 9007199254740992LLU,
      register_ = 18014398509481984LLU,
      safeGroup = 60129542144LLU,
      IOR = 2103296LLU,
      TYPECTOR = 2685403140LLU,
      FUNCATTR = 9011661828521984LLU,
  };
  
  static STC const STCFlowThruAggregate = (STC)60129542144LLU;
  
  static STC const STCFlowThruFunction = (STC)18446726413102348896LLU;
  
  static STC const STCStorageClass = (STC)12407095344775071LLU;
  
  static const char* const package_d = "package.d";
  
  static const char* const package_di = "package.di";
  
  enum class StructFlags
  {
      none = 0,
      hasPointers = 1,
  };
  
  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 : int32_t { WANTexpand = 1 };
  
  enum : int32_t { WANTvalue = 0 };
  
  typedef bool(*fp2_t)(Loc& loc, TOK , 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,
      strong = 4u,
  };
  
  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;
      DsymbolTable* localsymtab;
      VarDeclaration* vthis;
      bool isThis2;
      VarDeclaration* v_arguments;
      VarDeclaration* v_argptr;
      Array<VarDeclaration* >* parameters;
      DsymbolTable* labtab;
      Dsymbol* overnext;
      FuncDeclaration* overnext0;
      Loc endloc;
      int32_t vtblIndex;
      bool naked;
      bool generated;
      bool hasAlwaysInlines;
      uint8_t isCrtCtorDtor;
      ILS inlineStatusStmt;
      ILS inlineStatusExp;
      PINLINE inlining;
      int32_t inlineNest;
      bool eh_none;
      bool semantic3Errors;
      ForeachStatement* fes;
      BaseClass* interfaceVirtual;
      bool introducing;
      Type* tintro;
      bool inferRetType;
      StorageClass storage_class2;
      int32_t hasReturnExp;
      bool nrvo_can;
      VarDeclaration* nrvo_var;
      Symbol* shidden;
      Array<ReturnStatement* >* returns;
      Array<GotoStatement* >* gotos;
      BUILTIN builtin;
      int32_t tookAddressOf;
      bool requiresClosure;
      Array<VarDeclaration* > closureVars;
      Array<VarDeclaration* > outerVars;
      Array<FuncDeclaration* > siblingCallers;
      Array<FuncDeclaration* >* inlinedNestedCallees;
      uint32_t flags;
      ObjcFuncDeclaration objc;
      static FuncDeclaration* create(const Loc& loc, const Loc& endloc, Identifier* id, StorageClass storage_class, Type* type);
      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();
      virtual bool isNested() const;
      AggregateDeclaration* isThis();
      bool needThis();
      bool isVirtualMethod();
      virtual bool isVirtual() const;
      bool isFinalFunc() const;
      virtual bool addPreInvariant();
      virtual bool addPostInvariant();
      const char* kind() const;
      bool isUnique() const;
      bool needsClosure();
      bool hasNestedFrameRefs();
      static bool needsFensure(FuncDeclaration* fd);
      void buildEnsureRequire();
      ParameterList getParameterList();
      static FuncDeclaration* genCfunc(Array<Parameter* >* fparams, Type* treturn, const char* name, StorageClass stc = 0);
      static FuncDeclaration* genCfunc(Array<Parameter* >* fparams, Type* treturn, Identifier* id, StorageClass stc = 0);
      bool checkNRVO();
      FuncDeclaration* isFuncDeclaration();
      virtual FuncDeclaration* toAliasFunc();
      void accept(Visitor* v);
      ~FuncDeclaration();
  };
  
  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);
      ~CtorDeclaration();
  };
  
  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);
      ~DtorDeclaration();
  };
  
  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,
  };
  
  class FuncAliasDeclaration final : public FuncDeclaration
  {
  public:
      FuncDeclaration* funcalias;
      bool hasOverloads;
      FuncAliasDeclaration* isFuncAliasDeclaration();
      const char* kind() const;
      FuncDeclaration* toAliasFunc();
      void accept(Visitor* v);
      ~FuncAliasDeclaration();
  };
  
  class FuncLiteralDeclaration final : public FuncDeclaration
  {
  public:
      TOK tok;
      Type* treq;
      bool deferToObj;
      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);
      ~FuncLiteralDeclaration();
  };
  
  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);
      ~InvariantDeclaration();
  };
  
  class NewDeclaration final : public FuncDeclaration
  {
  public:
      ParameterList parameterList;
      NewDeclaration* syntaxCopy(Dsymbol* s);
      const char* kind() const;
      bool isVirtual() const;
      bool addPreInvariant();
      bool addPostInvariant();
      NewDeclaration* isNewDeclaration();
      void accept(Visitor* v);
      ~NewDeclaration();
  };
  
  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);
      ~PostBlitDeclaration();
  };
  
  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);
      ~StaticCtorDeclaration();
  };
  
  class SharedStaticCtorDeclaration final : public StaticCtorDeclaration
  {
  public:
      SharedStaticCtorDeclaration* syntaxCopy(Dsymbol* s);
      SharedStaticCtorDeclaration* isSharedStaticCtorDeclaration();
      void accept(Visitor* v);
      ~SharedStaticCtorDeclaration();
  };
  
  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);
      ~StaticDtorDeclaration();
  };
  
  class SharedStaticDtorDeclaration final : public StaticDtorDeclaration
  {
  public:
      SharedStaticDtorDeclaration* syntaxCopy(Dsymbol* s);
      SharedStaticDtorDeclaration* isSharedStaticDtorDeclaration();
      void accept(Visitor* v);
      ~SharedStaticDtorDeclaration();
  };
  
  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);
      ~UnitTestDeclaration();
  };
  
  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);
      ~ArrayInitializer();
  };
  
  class CInitializer final : public Initializer
  {
  public:
      Array<DesigInit > initializerList;
      Type* type;
      bool sem;
      void accept(Visitor* v);
      ~CInitializer();
  };
  
  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);
      ~StructInitializer();
  };
  
  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);
  
  enum class DotExpFlag
  {
      gag = 1,
      noDeref = 2,
  };
  
  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,
  };
  
  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();
      d_uns64 size(const Loc& loc) /* const */;
      bool isZeroInit(const Loc& loc) /* const */;
      bool isBoolean() /* const */;
      bool hasPointers() /* const */;
      MATCH implicitConvTo(Type* to);
      MATCH constConv(Type* to);
      void accept(Visitor* v);
  };
  
  class TypeBasic final : public Type
  {
  public:
      const char* dstring;
      uint32_t flags;
      const char* kind() const;
      TypeBasic* syntaxCopy();
      d_uns64 size(const Loc& loc) /* const */;
      uint32_t alignsize();
      bool isintegral();
      bool isfloating() /* const */;
      bool isreal() /* const */;
      bool isimaginary() /* const */;
      bool iscomplex() /* const */;
      bool isscalar() /* const */;
      bool isunsigned() /* const */;
      MATCH implicitConvTo(Type* to);
      bool isZeroInit(const Loc& loc) /* const */;
      TypeBasic* isTypeBasic();
      void accept(Visitor* v);
  };
  
  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;
      d_uns64 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();
      d_uns64 size(const Loc& loc) /* const */;
      uint32_t alignsize() /* const */;
      bool isString();
      bool isZeroInit(const Loc& loc) /* const */;
      bool isBoolean() /* const */;
      MATCH implicitConvTo(Type* to);
      bool hasPointers() /* const */;
      void accept(Visitor* v);
  };
  
  class TypeDelegate final : public TypeNext
  {
  public:
      static TypeDelegate* create(TypeFunction* t);
      const char* kind() const;
      TypeDelegate* syntaxCopy();
      Type* addStorageClass(StorageClass stc);
      d_uns64 size(const Loc& loc) /* const */;
      uint32_t alignsize() /* const */;
      MATCH implicitConvTo(Type* to);
      bool isZeroInit(const Loc& loc) /* const */;
      bool isBoolean() /* const */;
      bool hasPointers() /* const */;
      void accept(Visitor* v);
  };
  
  class TypeEnum final : public Type
  {
  public:
      EnumDeclaration* sym;
      const char* kind() const;
      TypeEnum* syntaxCopy();
      d_uns64 size(const Loc& loc);
      Type* memType(const Loc& loc = Loc::initial);
      uint32_t alignsize();
      Dsymbol* toDsymbol(Scope* sc);
      bool isintegral();
      bool isfloating();
      bool isreal();
      bool isimaginary();
      bool iscomplex();
      bool isscalar();
      bool isunsigned();
      bool isBoolean();
      bool isString();
      bool isAssignable();
      bool needsDestruction();
      bool needsCopyOrPostblit();
      bool needsNested();
      MATCH implicitConvTo(Type* to);
      MATCH constConv(Type* to);
      bool isZeroInit(const Loc& loc);
      bool hasPointers();
      bool hasVoidInitPointers();
      bool hasInvariant();
      Type* nextOf();
      void accept(Visitor* v);
  };
  
  class TypeError final : public Type
  {
  public:
      const char* kind() const;
      TypeError* syntaxCopy();
      d_uns64 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:
      enum class FunctionFlag : uint32_t
      {
          none = 0u,
          isnothrow = 1u,
          isnogc = 2u,
          isproperty = 4u,
          isref = 8u,
          isreturn = 16u,
          isscope = 32u,
          isreturninferred = 64u,
          isscopeinferred = 128u,
          islive = 256u,
          incomplete = 512u,
          inoutParam = 1024u,
          inoutQual = 2048u,
      };
  
  public:
      LINK linkage;
      FunctionFlag funcFlags;
      TRUST trust;
      PURE purity;
      int8_t inuse;
      Array<Expression* >* fargs;
      static TypeFunction* create(Array<Parameter* >* parameters, Type* treturn, uint8_t varargs, LINK linkage, StorageClass stc = 0);
      const char* kind() const;
      TypeFunction* syntaxCopy();
      void purityLevel();
      bool hasLazyParameters();
      bool isDstyleVariadic() const;
      bool parameterEscapes(Type* tthis, Parameter* p);
      StorageClass parameterStorageClass(Type* tthis, Parameter* p);
      Type* addStorageClass(StorageClass stc);
      Type* substWildTo(uint32_t _param_0);
      MATCH constConv(Type* to);
      bool isnothrow() const;
      void isnothrow(bool v);
      bool isnogc() const;
      void isnogc(bool v);
      bool isproperty() const;
      void isproperty(bool v);
      bool isref() const;
      void isref(bool v);
      bool isreturn() const;
      void isreturn(bool v);
      bool isScopeQual() const;
      void isScopeQual(bool v);
      bool isreturninferred() const;
      void isreturninferred(bool v);
      bool isscopeinferred() const;
      void isscopeinferred(bool v);
      bool islive() const;
      void islive(bool v);
      bool incomplete() const;
      void incomplete(bool v);
      bool isInOutParam() const;
      void isInOutParam(bool v);
      bool isInOutQual() const;
      void isInOutQual(bool v);
      bool iswild() const;
      bool attributesEqual(const TypeFunction* const other) const;
      void accept(Visitor* v);
  };
  
  class 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);
      d_uns64 size(const Loc& loc);
      void accept(Visitor* v);
      ~TypeQualified();
  };
  
  class TypeIdentifier final : public TypeQualified
  {
  public:
      Identifier* ident;
      Dsymbol* originalSymbol;
      const char* kind() const;
      TypeIdentifier* syntaxCopy();
      Dsymbol* toDsymbol(Scope* sc);
      void accept(Visitor* v);
      ~TypeIdentifier();
  };
  
  class TypeInstance final : public TypeQualified
  {
  public:
      TemplateInstance* tempinst;
      const char* kind() const;
      TypeInstance* syntaxCopy();
      Dsymbol* toDsymbol(Scope* sc);
      void accept(Visitor* v);
      ~TypeInstance();
  };
  
  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 */;
      d_uns64 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 */;
      d_uns64 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();
      d_uns64 size(const Loc& loc) /* const */;
      MATCH implicitConvTo(Type* to);
      MATCH constConv(Type* to);
      bool isscalar() /* const */;
      bool isZeroInit(const Loc& loc) /* const */;
      bool hasPointers() /* const */;
      void accept(Visitor* v);
  };
  
  class TypeReference final : public TypeNext
  {
  public:
      const char* kind() const;
      TypeReference* syntaxCopy();
      d_uns64 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);
      ~TypeReturn();
  };
  
  class TypeSArray final : public TypeArray
  {
  public:
      Expression* dim;
      const char* kind() const;
      TypeSArray* syntaxCopy();
      d_uns64 size(const Loc& loc);
      uint32_t alignsize();
      bool isString();
      bool isZeroInit(const Loc& loc);
      uint32_t alignment();
      MATCH constConv(Type* to);
      MATCH implicitConvTo(Type* to);
      Expression* defaultInitLiteral(const Loc& loc);
      bool hasPointers();
      bool 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;
      d_uns64 size(const Loc& loc);
      uint32_t alignsize();
      TypeStruct* syntaxCopy();
      Dsymbol* toDsymbol(Scope* sc);
      uint32_t alignment();
      Expression* defaultInitLiteral(const Loc& loc);
      bool isZeroInit(const Loc& loc);
      bool isAssignable();
      bool isBoolean() /* const */;
      bool needsDestruction() /* const */;
      bool needsCopyOrPostblit();
      bool needsNested();
      bool hasPointers();
      bool hasVoidInitPointers();
      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;
      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);
      d_uns64 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;
      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);
      d_uns64 size(const Loc& loc);
      void accept(Visitor* v);
      ~TypeTypeof();
  };
  
  class TypeVector final : public Type
  {
  public:
      Type* basetype;
      static TypeVector* create(Type* basetype);
      const char* kind() const;
      TypeVector* syntaxCopy();
      d_uns64 size(const Loc& loc);
      uint32_t alignsize();
      bool isintegral();
      bool isfloating();
      bool isscalar();
      bool isunsigned();
      bool isBoolean() /* const */;
      MATCH implicitConvTo(Type* to);
      Expression* defaultInitLiteral(const Loc& loc);
      TypeBasic* elementType();
      bool isZeroInit(const Loc& loc);
      void accept(Visitor* v);
  };
  
  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, uint32_t* poffset, bool isunion);
      const char* kind() const;
      Nspace* isNspace();
      void accept(Visitor* v);
      ~Nspace();
  };
  
  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(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(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);
      ~SwitchStatement();
  };
  
  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(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;
      void accept(Visitor* v);
  };
  
  extern Type* typeSemantic(Type* type, const Loc& loc, Scope* sc);
  
  enum class MODFlags
  {
      const_ = 1,
      immutable_ = 4,
      shared_ = 2,
      wild = 8,
      wildconst = 9,
      mutable_ = 16,
  };
  
  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 Abstract = ::Abstract;
      using BaseClass = ::BaseClass;
      using ClassDeclaration = ::ClassDeclaration;
      using ClassFlags = ::ClassFlags;
      using InterfaceDeclaration = ::InterfaceDeclaration;
      using AliasDeclaration = ::AliasDeclaration;
      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 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 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 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 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 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 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 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,
      };
  
      uint8_t longsize;
      uint8_t long_doublesize;
      uint8_t wchar_tsize;
      Runtime runtime;
      TargetC() :
          longsize(),
          long_doublesize(),
          wchar_tsize()
      {
      }
      TargetC(uint8_t longsize, uint8_t long_doublesize = 0u, uint8_t wchar_tsize = 0u, Runtime runtime = (Runtime)0u) :
          longsize(longsize),
          long_doublesize(long_doublesize),
          wchar_tsize(wchar_tsize),
          runtime(runtime)
          {}
  };
  
  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 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(Parameter* p);
      bool fundamentalType(const Type* const t, bool& isFundamental);
      uint32_t derivedClassOffset(ClassDeclaration* baseClass);
      TargetCPP() :
          reverseOverloads(),
          exceptions(),
          twoDtorInVtable(),
          wrapDtorInExternD()
      {
      }
      TargetCPP(bool reverseOverloads, bool exceptions = false, bool twoDtorInVtable = false, bool wrapDtorInExternD = false, Runtime runtime = (Runtime)0u) :
          reverseOverloads(reverseOverloads),
          exceptions(exceptions),
          twoDtorInVtable(twoDtorInVtable),
          wrapDtorInExternD(wrapDtorInExternD),
          runtime(runtime)
          {}
  };
  
  struct TargetObjC final
  {
      bool supported;
      TargetObjC() :
          supported()
      {
      }
      TargetObjC(bool supported) :
          supported(supported)
          {}
  };
  
  enum class CPU
  {
      x87 = 0,
      mmx = 1,
      sse = 2,
      sse2 = 3,
      sse3 = 4,
      ssse3 = 5,
      sse4_1 = 6,
      sse4_2 = 7,
      avx = 8,
      avx2 = 9,
      avx512 = 10,
      baseline = 11,
      native = 12,
  };
  
  typedef _d_real longdouble;
  
  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;
      NewDeclaration* aggNew;
      Dsymbol* ctor;
      CtorDeclaration* defaultCtor;
      AliasThis* aliasthis;
      Array<DtorDeclaration* > dtors;
      DtorDeclaration* dtor;
      DtorDeclaration* primaryDtor;
      DtorDeclaration* tidtor;
      FuncDeclaration* fieldDtor;
      Expression* getRTInfo;
      Visibility visibility;
      bool noDefaultCtor;
      Sizeok sizeok;
      virtual Scope* newScope(Scope* sc);
      void setScope(Scope* sc);
      bool determineFields();
      size_t nonHiddenFields();
      bool determineSize(Loc loc);
      virtual void finalizeSize() = 0;
      d_uns64 size(const Loc& loc);
      bool fill(Loc loc, Array<Expression* >* elements, bool ctorinit);
      Type* getType();
      bool isDeprecated() const;
      void setDeprecated();
      bool isNested() const;
      bool isExport() const;
      Dsymbol* searchCtor();
      Visibility visible();
      Type* handleType();
      bool hasInvariant();
      void* sinit;
      AggregateDeclaration* isAggregateDeclaration();
      void accept(Visitor* v);
      ~AggregateDeclaration();
  };
  
  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, uint32_t* poffset, bool isunion);
      bool hasPointers();
      bool hasStaticCtorOrDtor();
      void checkCtorConstInit();
      void addLocalClass(Array<ClassDeclaration* >* aclasses);
      void addObjcSymbols(Array<ClassDeclaration* >* classes, Array<ClassDeclaration* >* categories);
      AttribDeclaration* isAttribDeclaration();
      void accept(Visitor* v);
  };
  
  class StorageClassDeclaration : public AttribDeclaration
  {
  public:
      StorageClass stc;
      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:
      Expression* ealign;
      enum : uint32_t { UNKNOWN = 0u };
  
      uint32_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, uint32_t* poffset, 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(Loc loc, FuncDeclaration* fd, Array<Expression* >* arguments);
  
  extern bool 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()
      {
      }
  };
  
  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;
  };
  
  extern _d_real creall(complex_t x);
  
  extern _d_real cimagl(complex_t x);
  
  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);
  
  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();
      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:
      Abstract isabstract;
      Baseok baseok;
      ObjcClassDeclaration objc;
      Symbol* cpp_type_info_ptr_sym;
      static ClassDeclaration* create(Loc loc, Identifier* id, Array<BaseClass* >* baseclasses, Array<Dsymbol* >* members, bool inObject);
      const char* toPrettyChars(bool qualifyTypes = false);
      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);
      ~ClassDeclaration();
  };
  
  class InterfaceDeclaration final : public ClassDeclaration
  {
  public:
      InterfaceDeclaration* syntaxCopy(Dsymbol* s);
      Scope* newScope(Scope* sc);
      bool isBaseOf(ClassDeclaration* cd, int32_t* poffset);
      bool isBaseOf(BaseClass* bc, int32_t* poffset);
      const char* kind() const;
      int32_t vtblOffset() const;
      bool isCPPinterface() const;
      bool isCOMinterface() const;
      InterfaceDeclaration* isInterfaceDeclaration();
      void accept(Visitor* v);
      ~InterfaceDeclaration();
  };
  
  extern void ObjectNotFound(Identifier* id);
  
  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 };
  
      _d_dynamicArray< const char > mangleOverride;
      const char* kind() const;
      d_uns64 size(const Loc& loc);
      Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
      bool isStatic() const;
      virtual bool isDelete();
      virtual bool isDataseg();
      virtual bool isThreadlocal();
      virtual bool isCodeseg() const;
      bool isCtorinit() const;
      bool isFinal() const;
      virtual bool isAbstract();
      bool isConst() const;
      bool isImmutable() const;
      bool isWild() const;
      bool isAuto() const;
      bool isScope() const;
      bool isSynchronized() const;
      bool isParameter() const;
      bool isDeprecated() const;
      bool isDisabled() const;
      bool isOverride() const;
      bool isResult() const;
      bool isField() const;
      bool isIn() const;
      bool isOut() const;
      bool isRef() const;
      bool 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(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;
      static uint32_t nextSequenceNumber;
      uint32_t alignment;
      enum : uint32_t { AdrOnStackNone = 4294967295u };
  
      uint32_t ctfeAdrOnStack;
      bool isargptr;
      bool ctorinit;
      bool iscatchvar;
      bool isowner;
      bool onstack;
      bool mynew;
      int8_t canassign;
      bool overlapped;
      bool overlapUnsafe;
      bool doNotInferScope;
      bool doNotInferReturn;
      uint8_t isdataseg;
      bool isArgDtorVar;
      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, uint32_t* poffset, bool isunion);
      const char* kind() const;
      AggregateDeclaration* isThis();
      bool needThis();
      bool isExport() const;
      bool isImportedSymbol() const;
      bool isDataseg();
      bool isThreadlocal();
      bool isCTFE();
      bool isOverlappedWith(VarDeclaration* v);
      bool hasPointers();
      bool canTakeAddressOf();
      bool needsScopeDtor();
      void checkCtorConstInit();
      Dsymbol* toAlias();
      VarDeclaration* isVarDeclaration();
      void accept(Visitor* v);
      bool enclosesLifetimeOf(VarDeclaration* v) const;
      void addMaybe(VarDeclaration* v);
      ~VarDeclaration();
  };
  
  class SymbolDeclaration final : public Declaration
  {
  public:
      StructDeclaration* dsym;
      SymbolDeclaration* isSymbolDeclaration();
      void accept(Visitor* v);
  };
  
  class TypeInfoDeclaration : public VarDeclaration
  {
  public:
      Type* tinfo;
      static TypeInfoDeclaration* create(Type* tinfo);
      TypeInfoDeclaration* syntaxCopy(Dsymbol* s);
      const char* toChars() const;
      TypeInfoDeclaration* isTypeInfoDeclaration();
      void accept(Visitor* v);
      ~TypeInfoDeclaration();
  };
  
  class TypeInfoStructDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoStructDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoStructDeclaration();
  };
  
  class TypeInfoClassDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoClassDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoClassDeclaration();
  };
  
  class TypeInfoInterfaceDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoInterfaceDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoInterfaceDeclaration();
  };
  
  class TypeInfoPointerDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoPointerDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoPointerDeclaration();
  };
  
  class TypeInfoArrayDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoArrayDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoArrayDeclaration();
  };
  
  class TypeInfoStaticArrayDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoStaticArrayDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoStaticArrayDeclaration();
  };
  
  class TypeInfoAssociativeArrayDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoAssociativeArrayDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoAssociativeArrayDeclaration();
  };
  
  class TypeInfoEnumDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoEnumDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoEnumDeclaration();
  };
  
  class TypeInfoFunctionDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoFunctionDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoFunctionDeclaration();
  };
  
  class TypeInfoDelegateDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoDelegateDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoDelegateDeclaration();
  };
  
  class TypeInfoTupleDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoTupleDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoTupleDeclaration();
  };
  
  class TypeInfoConstDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoConstDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoConstDeclaration();
  };
  
  class TypeInfoInvariantDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoInvariantDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoInvariantDeclaration();
  };
  
  class TypeInfoSharedDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoSharedDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoSharedDeclaration();
  };
  
  class TypeInfoWildDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoWildDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoWildDeclaration();
  };
  
  class TypeInfoVectorDeclaration final : public TypeInfoDeclaration
  {
  public:
      static TypeInfoVectorDeclaration* create(Type* tinfo);
      void accept(Visitor* v);
      ~TypeInfoVectorDeclaration();
  };
  
  class ThisDeclaration final : public VarDeclaration
  {
  public:
      ThisDeclaration* syntaxCopy(Dsymbol* s);
      ThisDeclaration* isThisDeclaration();
      void accept(Visitor* v);
      ~ThisDeclaration();
  };
  
  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);
      ~EnumDeclaration();
  };
  
  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);
      ~EnumMember();
  };
  
  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);
      ~Import();
  };
  
  extern Expression* getValue(VarDeclaration* vd);
  
  extern void printCtfePerformanceStats();
  
  struct MacroTable final
  {
  private:
      Macro* mactab;
  public:
      MacroTable()
      {
      }
  };
  
  extern const char* mangleExact(FuncDeclaration* fd);
  
  extern void mangleToBuffer(Type* t, OutBuffer* buf);
  
  extern void mangleToBuffer(Expression* e, OutBuffer* buf);
  
  extern void mangleToBuffer(Dsymbol* s, OutBuffer* buf);
  
  extern void mangleToBuffer(TemplateInstance* ti, OutBuffer* buf);
  
  class Package : public ScopeDsymbol
  {
  public:
      PKG isPkgMod;
      uint32_t tag;
      Module* mod;
      const char* kind() const;
      bool equals(const RootObject* const o) const;
      Package* isPackage();
      bool isAncestorPackageOf(const Package* const pkg) const;
      Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
      void accept(Visitor* v);
      Module* isPackageMod();
      void resolvePKGunknown();
      ~Package();
  };
  
  class Module final : public Package
  {
  public:
      static Module* rootModule;
      static DsymbolTable* modules;
      static Array<Module* > amodules;
      static Array<Dsymbol* > deferred;
      static Array<Dsymbol* > deferred2;
      static Array<Dsymbol* > deferred3;
      static uint32_t dprogress;
      static void _init();
      static void deinitialize();
      static AggregateDeclaration* moduleinfo;
      _d_dynamicArray< const char > arg;
      ModuleDeclaration* md;
      const FileName srcfile;
      const FileName objfile;
      const FileName hdrfile;
      FileName docfile;
      FileBuffer* srcBuffer;
      uint32_t errors;
      uint32_t numlines;
      bool isHdrFile;
      bool isCFile;
      bool isDocFile;
      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(Loc loc, Array<Identifier* >* packages, Identifier* ident);
      const char* kind() const;
      bool loadSourceBuffer(const Loc& loc, File::ReadResult& readResult);
      bool read(const Loc& loc);
      Module* parse();
      void importAll(Scope* prevsc);
      int32_t needModuleInfo();
      void checkImportDeprecation(const Loc& loc, Scope* sc);
      Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
      bool isPackageAccessible(Package* p, 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);
      ~Module();
  };
  
  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;
      uint32_t alignment;
      StructPOD ispod;
      TypeTuple* argTypes;
      static StructDeclaration* create(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);
      ~StructDeclaration();
  };
  
  class UnionDeclaration final : public StructDeclaration
  {
  public:
      UnionDeclaration* syntaxCopy(Dsymbol* s);
      const char* kind() const;
      UnionDeclaration* isUnionDeclaration();
      void accept(Visitor* v);
      ~UnionDeclaration();
  };
  
  class WithScopeSymbol final : public ScopeDsymbol
  {
  public:
      WithStatement* withstate;
      Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 8);
      WithScopeSymbol* isWithScopeSymbol();
      void accept(Visitor* v);
      ~WithScopeSymbol();
  };
  
  class ArrayScopeSymbol final : public ScopeDsymbol
  {
      RootObject* arrayContent;
  public:
      Scope* sc;
      Dsymbol* search(const Loc& loc, Identifier* ident, int32_t flags = 0);
      ArrayScopeSymbol* isArrayScopeSymbol();
      void accept(Visitor* v);
      ~ArrayScopeSymbol();
  };
  
  class OverloadSet final : public Dsymbol
  {
  public:
      Array<Dsymbol* > a;
      void push(Dsymbol* s);
      OverloadSet* isOverloadSet();
      const char* kind() const;
      void accept(Visitor* v);
      ~OverloadSet();
  };
  
  class ForwardingScopeDsymbol final : public ScopeDsymbol
  {
  public:
      ScopeDsymbol* forward;
      Dsymbol* symtabInsert(Dsymbol* s);
      Dsymbol* symtabLookup(Dsymbol* s, Identifier* id);
      void importScope(Dsymbol* s, Visibility visibility);
      const char* kind() const;
      ForwardingScopeDsymbol* isForwardingScopeDsymbol();
      ~ForwardingScopeDsymbol();
  };
  
  class ExpressionDsymbol final : public Dsymbol
  {
  public:
      Expression* exp;
      ExpressionDsymbol(Expression* exp);
      ExpressionDsymbol* isExpressionDsymbol();
  };
  
  class AliasAssign final : public Dsymbol
  {
  public:
      Identifier* ident;
      Type* type;
      Dsymbol* 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;
      ~Tuple();
  };
  
  class TemplateDeclaration final : public ScopeDsymbol
  {
  public:
      Array<TemplateParameter* >* parameters;
      Array<TemplateParameter* >* origParameters;
      Expression* constraint;
      void* instances;
      TemplateDeclaration* overnext;
      TemplateDeclaration* overroot;
      FuncDeclaration* funcroot;
      Dsymbol* onemember;
      bool literal;
      bool ismixin;
      bool isstatic;
      bool isTrivialAliasSeq;
      bool isTrivialAlias;
      bool deprecated_;
      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);
      ~TemplateDeclaration();
  };
  
  class TypeDeduced final : public Type
  {
  public:
      Type* tded;
      Array<Expression* > argexps;
      Array<Type* > tparams;
      void update(Expression* e, Type* tparam);
      void update(Type* tt, Expression* e, Type* tparam);
      MATCH matchAll(Type* tt);
      ~TypeDeduced();
  };
  
  class TemplateParameter : public ASTNode
  {
  public:
      Loc loc;
      Identifier* ident;
      bool dependent;
      virtual TemplateTypeParameter* isTemplateTypeParameter();
      virtual TemplateValueParameter* isTemplateValueParameter();
      virtual TemplateAliasParameter* isTemplateAliasParameter();
      virtual TemplateThisParameter* isTemplateThisParameter();
      virtual TemplateTupleParameter* isTemplateTupleParameter();
      virtual TemplateParameter* syntaxCopy() = 0;
      virtual bool declareParameter(Scope* sc) = 0;
      virtual void print(RootObject* oarg, RootObject* oded) = 0;
      virtual RootObject* specialization() = 0;
      virtual RootObject* defaultArg(Loc instLoc, Scope* sc) = 0;
      virtual bool hasDefaultArg() = 0;
      const char* toChars() const;
      DYNCAST dyncast() const;
      virtual RootObject* dummyArg() = 0;
      void accept(Visitor* v);
  };
  
  class TemplateTypeParameter : public TemplateParameter
  {
  public:
      Type* specType;
      Type* defaultType;
      TemplateTypeParameter* isTemplateTypeParameter();
      TemplateTypeParameter* syntaxCopy();
      bool declareParameter(Scope* sc);
      void print(RootObject* oarg, RootObject* oded);
      RootObject* specialization();
      RootObject* defaultArg(Loc instLoc, Scope* sc);
      bool hasDefaultArg();
      RootObject* dummyArg();
      void accept(Visitor* v);
  };
  
  class TemplateThisParameter final : public TemplateTypeParameter
  {
  public:
      TemplateThisParameter* isTemplateThisParameter();
      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(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(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(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);
      ~TemplateInstance();
  };
  
  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, uint32_t* poffset, bool isunion);
      const char* toChars() const;
      TemplateMixin* isTemplateMixin();
      void accept(Visitor* v);
      ~TemplateMixin();
  };
  
  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(Loc loc, dinteger_t value, Type* type);
      static void emplace(UnionExp* pue, Loc loc, dinteger_t value, Type* type);
      bool equals(const RootObject* const o) const;
      dinteger_t toInteger();
      _d_real toReal();
      _d_real toImaginary();
      complex_t toComplex();
      bool isBool(bool result);
      Expression* toLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
      dinteger_t getInteger();
      void setInteger(dinteger_t value);
      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(Loc loc, _d_real value, Type* type);
      static void emplace(UnionExp* pue, Loc loc, _d_real value, Type* type);
      bool equals(const RootObject* const o) const;
      dinteger_t toInteger();
      uinteger_t toUInteger();
      _d_real toReal();
      _d_real toImaginary();
      complex_t toComplex();
      bool isBool(bool result);
      void accept(Visitor* v);
  };
  
  class ComplexExp final : public Expression
  {
  public:
      complex_t value;
      static ComplexExp* create(Loc loc, complex_t value, Type* type);
      static void emplace(UnionExp* pue, Loc loc, complex_t value, Type* type);
      bool equals(const RootObject* const o) const;
      dinteger_t toInteger();
      uinteger_t toUInteger();
      _d_real toReal();
      _d_real toImaginary();
      complex_t toComplex();
      bool isBool(bool result);
      void accept(Visitor* v);
  };
  
  class IdentifierExp : public Expression
  {
  public:
      Identifier* ident;
      static IdentifierExp* create(Loc loc, Identifier* ident);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
  };
  
  class DollarExp final : public IdentifierExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class DsymbolExp final : public Expression
  {
  public:
      Dsymbol* s;
      bool hasOverloads;
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
  };
  
  class ThisExp : public Expression
  {
  public:
      VarDeclaration* var;
      ThisExp(const Loc& loc, const TOK tok);
      ThisExp* syntaxCopy();
      bool isBool(bool result);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
  };
  
  class SuperExp final : public ThisExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class NullExp final : public Expression
  {
  public:
      bool equals(const RootObject* const o) const;
      bool isBool(bool result);
      StringExp* toStringExp();
      void accept(Visitor* v);
  };
  
  class StringExp final : public Expression
  {
      union
      {
          char* string;
          char16_t* wstring;
          char32_t* dstring;
      };
  public:
      size_t len;
      uint8_t sz;
      uint8_t committed;
      enum : char { NoPostfix = 0u };
  
      char postfix;
      OwnedBy ownedByCtfe;
      static StringExp* create(Loc loc, char* s);
      static StringExp* create(Loc loc, void* string, size_t len);
      static void emplace(UnionExp* pue, Loc loc, char* s);
      bool equals(const RootObject* const o) const;
      size_t numberOfCodeUnits(int32_t tynto = 0) const;
      void writeTo(void* dest, bool zero, int32_t tyto = 0) const;
      char32_t getCodeUnit(size_t i) const;
      void setCodeUnit(size_t i, char32_t c);
      StringExp* toStringExp();
      StringExp* toUTF8(Scope* sc);
      int32_t compare(const StringExp* const se2) const;
      bool isBool(bool result);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      Expression* modifiableLvalue(Scope* sc, Expression* e);
      uint32_t charAt(uinteger_t i) const;
      void accept(Visitor* v);
  };
  
  class TupleExp final : public Expression
  {
  public:
      Expression* e0;
      Array<Expression* >* exps;
      static TupleExp* create(Loc loc, Array<Expression* >* exps);
      TupleExp* toTupleExp();
      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(Loc loc, Array<Expression* >* elements);
      static void emplace(UnionExp* pue, Loc loc, Array<Expression* >* elements);
      ArrayLiteralExp* syntaxCopy();
      bool equals(const RootObject* const o) const;
      Expression* getElement(size_t i);
      Expression* opIndex(size_t i);
      bool isBool(bool result);
      StringExp* toStringExp();
      void accept(Visitor* v);
  };
  
  class AssocArrayLiteralExp final : public Expression
  {
  public:
      Array<Expression* >* keys;
      Array<Expression* >* values;
      OwnedBy ownedByCtfe;
      bool equals(const RootObject* const o) const;
      AssocArrayLiteralExp* syntaxCopy();
      bool isBool(bool result);
      void accept(Visitor* v);
  };
  
  class StructLiteralExp final : public Expression
  {
  public:
      StructDeclaration* sd;
      Array<Expression* >* elements;
      Type* stype;
      Symbol* sym;
      StructLiteralExp* origin;
      StructLiteralExp* inlinecopy;
      int32_t stageflags;
      bool useStaticInit;
      bool isOriginal;
      OwnedBy ownedByCtfe;
      static StructLiteralExp* create(Loc loc, StructDeclaration* sd, void* elements, Type* stype = nullptr);
      bool equals(const RootObject* const o) const;
      StructLiteralExp* syntaxCopy();
      Expression* getField(Type* type, uint32_t offset);
      int32_t getFieldIndex(Type* type, uint32_t offset);
      Expression* addDtorHook(Scope* sc);
      void accept(Visitor* v);
  };
  
  class 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;
      Array<Expression* >* newargs;
      Type* newtype;
      Array<Expression* >* arguments;
      Expression* argprefix;
      CtorDeclaration* member;
      NewDeclaration* allocator;
      bool onstack;
      bool thrownew;
      static NewExp* create(Loc loc, Expression* thisexp, Array<Expression* >* newargs, Type* newtype, Array<Expression* >* arguments);
      NewExp* syntaxCopy();
      void accept(Visitor* v);
  };
  
  class NewAnonClassExp final : public Expression
  {
  public:
      Expression* thisexp;
      Array<Expression* >* newargs;
      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;
      bool isBool(bool result);
      void accept(Visitor* v);
  };
  
  class VarExp final : public SymbolExp
  {
  public:
      bool delegateWasExtracted;
      static VarExp* create(Loc loc, Declaration* var, bool hasOverloads = true);
      bool equals(const RootObject* const o) const;
      Modifiable checkModifiable(Scope* sc, int32_t flag);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      Expression* modifiableLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
  };
  
  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);
      BinAssignExp* isBinAssignExp();
      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 DotIdExp final : public UnaExp
  {
  public:
      Identifier* ident;
      bool noderef;
      bool wantsym;
      static DotIdExp* create(Loc loc, Expression* e, Identifier* ident);
      void accept(Visitor* v);
  };
  
  class DotTemplateExp final : public UnaExp
  {
  public:
      TemplateDeclaration* td;
      void accept(Visitor* v);
  };
  
  class DotVarExp final : public UnaExp
  {
  public:
      Declaration* var;
      bool hasOverloads;
      Modifiable checkModifiable(Scope* sc, int32_t flag);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      Expression* modifiableLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
  };
  
  class DotTemplateInstanceExp final : public UnaExp
  {
  public:
      TemplateInstance* ti;
      DotTemplateInstanceExp* syntaxCopy();
      bool findTempDecl(Scope* sc);
      void accept(Visitor* v);
  };
  
  class DelegateExp final : public UnaExp
  {
  public:
      FuncDeclaration* func;
      bool hasOverloads;
      VarDeclaration* vthis2;
      void accept(Visitor* v);
  };
  
  class DotTypeExp final : public UnaExp
  {
  public:
      Dsymbol* sym;
      void accept(Visitor* v);
  };
  
  class CallExp final : public UnaExp
  {
  public:
      Array<Expression* >* arguments;
      FuncDeclaration* f;
      bool directcall;
      bool inDebugStatement;
      bool ignoreAttributes;
      VarDeclaration* vthis2;
      static CallExp* create(Loc loc, Expression* e, Array<Expression* >* exps);
      static CallExp* create(Loc loc, Expression* e);
      static CallExp* create(Loc loc, Expression* e, Expression* earg1);
      static CallExp* create(Loc loc, FuncDeclaration* fd, Expression* earg1);
      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:
      Modifiable checkModifiable(Scope* sc, int32_t flag);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      Expression* modifiableLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
  };
  
  class NegExp final : public UnaExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class UAddExp final : public UnaExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class ComExp final : public UnaExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class NotExp final : public UnaExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class DeleteExp final : public UnaExp
  {
  public:
      bool isRAII;
      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(Loc loc, Expression* e, Type* t);
      static void emplace(UnionExp* pue, 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();
      Modifiable checkModifiable(Scope* sc, int32_t flag);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      Expression* modifiableLvalue(Scope* sc, Expression* e);
      bool isBool(bool result);
      void accept(Visitor* v);
  };
  
  class ArrayLengthExp final : public UnaExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class ArrayExp final : public UnaExp
  {
  public:
      Array<Expression* >* arguments;
      size_t currentDimension;
      VarDeclaration* lengthVar;
      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;
      Modifiable checkModifiable(Scope* sc, int32_t flag);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      Expression* modifiableLvalue(Scope* sc, Expression* e);
      bool isBool(bool result);
      Expression* 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();
      Modifiable checkModifiable(Scope* sc, int32_t flag);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* e);
      Expression* modifiableLvalue(Scope* sc, Expression* e);
      void accept(Visitor* v);
  };
  
  class PostExp final : public BinExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class PreExp final : public UnaExp
  {
  public:
      void accept(Visitor* v);
  };
  
  class AssignExp : public BinExp
  {
  public:
      MemorySet memset;
      AssignExp(const Loc& loc, TOK tok, Expression* e1, Expression* e2);
      bool isLvalue();
      Expression* toLvalue(Scope* sc, Expression* ex);
      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();
      Modifiable checkModifiable(Scope* sc, int32_t flag);
      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);
  };
  
  extern Expression* resolveProperties(Scope* sc, Expression* e);
  
  extern Expression* expressionSemantic(Expression* e, Scope* sc);
  
  class NrvoWalker final : public StatementRewriteWalker
  {
  public:
      using StatementRewriteWalker::visit;
      FuncDeclaration* fd;
      Scope* sc;
      void visit(ReturnStatement* s);
      void visit(TryFinallyStatement* s);
  };
  
  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 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
      {
          Freestanding = 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 mscoff;
      template <typename T>
      struct FPTypeProperties final
      {
          // Ignoring var max alignment 0
          real_t max;
          // Ignoring var min_normal alignment 0
          real_t min_normal;
          // Ignoring var nan alignment 0
          real_t nan;
          // Ignoring var infinity alignment 0
          real_t infinity;
          // Ignoring var epsilon alignment 0
          real_t epsilon;
          // Ignoring var dig alignment 0
          d_int64 dig;
          // Ignoring var mant_dig alignment 0
          d_int64 mant_dig;
          // Ignoring var max_exp alignment 0
          d_int64 max_exp;
          // Ignoring var min_exp alignment 0
          d_int64 min_exp;
          // Ignoring var max_10_exp alignment 0
          d_int64 max_10_exp;
          // Ignoring var min_10_exp alignment 0
          d_int64 min_10_exp;
          FPTypeProperties()
          {
          }
      };
  
      FPTypeProperties<float > FloatProperties;
      FPTypeProperties<double > DoubleProperties;
      FPTypeProperties<_d_real > RealProperties;
  private:
      Type* tvalist;
      const Param* params;
  public:
      void _init(const Param& params);
      void setCPU();
      void setTriple(const Triple& triple);
      void addPredefinedGlobalIdentifiers() const;
      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, uint32_t op, Type* t2 = nullptr);
      LINK systemLinkage();
      TypeTuple* toArgTypes(Type* t);
      bool isReturnOnStack(TypeFunction* tf, bool needsThis);
      uint64_t parameterSize(const Loc& loc, Type* t);
      bool preferPassByRef(Type* t);
  private:
      enum class TargetInfoKeys
      {
          cppRuntimeLibrary = 0,
          cppStd = 1,
          floatAbi = 2,
          objectFormat = 3,
      };
  
  public:
      Expression* getTargetInfo(const char* name, const Loc& loc);
      bool isCalleeDestroyingArgs(TypeFunction* tf);
      bool libraryObjectMonitors(FuncDeclaration* fd, Statement* fbody);
      Target() :
          os((OS)1u),
          osMajor(),
          ptrsize(),
          realsize(),
          realpad(),
          realalignsize(),
          classinfosize(),
          maxStaticDataSize(),
          c(),
          cpp(),
          objc(),
          architectureName(),
          cpu((CPU)11),
          is64bit(true),
          isLP64(),
          obj_ext(),
          lib_ext(),
          dll_ext(),
          run_noext(),
          mscoff(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(0u, 0u, 0u, (TargetC::Runtime)0u), TargetCPP cpp = TargetCPP(false, false, false, false, (TargetCPP::Runtime)0u), TargetObjC objc = TargetObjC(false), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)11, 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 mscoff = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(NAN, NAN, NAN, NAN, NAN, 6LL, 24LL, 128LL, -125LL, 38LL, -37LL), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(NAN, NAN, NAN, NAN, NAN, 15LL, 53LL, 1024LL, -1021LL, 308LL, -307LL), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(NAN, NAN, NAN, NAN, NAN, 18LL, 64LL, 16384LL, -16381LL, 4932LL, -4931LL)) :
          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),
          mscoff(mscoff),
          FloatProperties(FloatProperties),
          DoubleProperties(DoubleProperties),
          RealProperties(RealProperties)
          {}
  };
  
  extern Target target;
  
  extern bool tpsemantic(TemplateParameter* tp, Scope* sc, Array<TemplateParameter* >* parameters);
  
  extern Type* getTypeInfoType(Loc loc, Type* t, Scope* sc);
  
  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(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 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* q;
      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* 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* 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* 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* 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* TRUE;
      static Identifier* FALSE;
      static Identifier* dllimport;
      static Identifier* dllexport;
      static Identifier* vector_size;
      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(uint32_t value);
      Token() :
          next(),
          loc(),
          ptr(),
          blockComment(),
          lineComment()
      {
      }
      Token(Token* next, Loc loc = Loc(nullptr, 0u, 0u), 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);
  
  