diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index 4935e6a1f5d..f8d2f45706a 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -10,12 +10,10 @@
 
 #pragma once
 
-#include "root/root.h"
-
 #include "dsymbol.h"
-#include "declaration.h"
 #include "objc.h"
 
+class AliasThis;
 class Identifier;
 class Type;
 class TypeFunction;
@@ -23,65 +21,51 @@ class Expression;
 class FuncDeclaration;
 class CtorDeclaration;
 class DtorDeclaration;
-class InvariantDeclaration;
-class NewDeclaration;
-class DeleteDeclaration;
 class InterfaceDeclaration;
 class TypeInfoClassDeclaration;
 class VarDeclaration;
 
-enum Sizeok
+enum class Sizeok : uint8_t
 {
-    SIZEOKnone,         // size of aggregate is not yet able to compute
-    SIZEOKfwd,          // size of aggregate is ready to compute
-    SIZEOKdone          // size of aggregate is set correctly
+    none,         // size of aggregate is not yet able to compute
+    fwd,          // size of aggregate is ready to compute
+    inProcess,    // in the midst of computing the size
+    done          // size of aggregate is set correctly
 };
 
-enum Baseok
+enum class Baseok : uint8_t
 {
-    BASEOKnone,         // base classes not computed yet
-    BASEOKin,           // in process of resolving base classes
-    BASEOKdone,         // all base classes are resolved
-    BASEOKsemanticdone  // all base classes semantic done
+    none,         // base classes not computed yet
+    in,           // in process of resolving base classes
+    done,         // all base classes are resolved
+    semanticdone  // all base classes semantic done
 };
 
-enum StructPOD
+enum class ThreeState : uint8_t
 {
-    ISPODno,            // struct is not POD
-    ISPODyes,           // struct is POD
-    ISPODfwd            // POD not yet computed
+    none,         // value not yet computed
+    no,           // value is false
+    yes,          // value is true
 };
 
-enum Abstract
+FuncDeclaration *search_toString(StructDeclaration *sd);
+
+enum class ClassKind : uint8_t
 {
-    ABSfwdref = 0,      // whether an abstract class is not yet computed
-    ABSyes,             // is abstract class
-    ABSno               // is not abstract class
+  /// the aggregate is a d(efault) struct/class/interface
+  d,
+  /// the aggregate is a C++ struct/class/interface
+  cpp,
+  /// the aggregate is an Objective-C class/interface
+  objc,
+  /// the aggregate is a C struct
+  c,
 };
 
-FuncDeclaration *hasIdentityOpAssign(AggregateDeclaration *ad, Scope *sc);
-FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc);
-bool needOpEquals(StructDeclaration *sd);
-FuncDeclaration *buildOpEquals(StructDeclaration *sd, Scope *sc);
-FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc);
-FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc);
-FuncDeclaration *buildXtoHash(StructDeclaration *ad, Scope *sc);
-FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc);
-FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc);
-FuncDeclaration *buildInv(AggregateDeclaration *ad, Scope *sc);
-FuncDeclaration *search_toString(StructDeclaration *sd);
-
-struct ClassKind
+struct MangleOverride
 {
-    enum Type
-    {
-        /// the class is a d(efault) class
-        d,
-        /// the class is a C++ interface
-        cpp,
-        /// the class is an Objective-C class/interface
-        objc,
-    };
+    Dsymbol *agg;
+    Identifier *id;
 };
 
 class AggregateDeclaration : public ScopeDsymbol
@@ -89,16 +73,16 @@ class AggregateDeclaration : public ScopeDsymbol
 public:
     Type *type;
     StorageClass storage_class;
-    Prot protection;
     unsigned structsize;        // size of struct
     unsigned alignsize;         // size of struct for alignment purposes
     VarDeclarations fields;     // VarDeclaration fields
-    Sizeok sizeok;              // set when structsize contains valid data
     Dsymbol *deferred;          // any deferred semantic2() or semantic3() symbol
-    bool isdeprecated;          // true if deprecated
 
-    ClassKind::Type classKind;  // specifies the linkage type
+    ClassKind classKind;        // specifies the linkage type
+    CPPMANGLE cppmangle;
 
+    // overridden symbol with pragma(mangle, "...")
+    MangleOverride *mangleOverride;
     /* !=NULL if is nested
      * pointing to the dsymbol that directly enclosing it.
      * 1. The function that enclosing it (nested struct and class)
@@ -108,11 +92,10 @@ public:
      */
     Dsymbol *enclosing;
     VarDeclaration *vthis;      // 'this' parameter if this aggregate is nested
+    VarDeclaration *vthis2;     // 'this' parameter if this aggregate is a template and is nested
     // Special member functions
     FuncDeclarations invs;              // Array of invariants
     FuncDeclaration *inv;               // invariant
-    NewDeclaration *aggNew;             // allocator
-    DeleteDeclaration *aggDelete;       // deallocator
 
     Dsymbol *ctor;                      // CtorDeclaration or TemplateDeclaration
 
@@ -120,42 +103,44 @@ public:
     // it would be stored in TypeInfo_Class.defaultConstructor
     CtorDeclaration *defaultCtor;
 
-    Dsymbol *aliasthis;         // forward unresolved lookups to aliasthis
-    bool noDefaultCtor;         // no default construction
+    AliasThis *aliasthis;       // forward unresolved lookups to aliasthis
 
-    FuncDeclarations dtors;     // Array of destructors
-    FuncDeclaration *dtor;      // aggregate destructor
+    DtorDeclarations dtors;     // Array of destructors
+    DtorDeclaration *dtor;      // aggregate destructor
+    DtorDeclaration *primaryDtor; // non-deleting C++ destructor, same as dtor for D
+    DtorDeclaration *tidtor;    // aggregate destructor used in TypeInfo (must have extern(D) ABI)
+    FuncDeclaration *fieldDtor;   // aggregate destructor for just the fields
 
     Expression *getRTInfo;      // pointer to GC info generated by object.RTInfo(this)
 
-    AggregateDeclaration(Loc loc, Identifier *id);
+    Visibility visibility;
+    bool noDefaultCtor;         // no default construction
+    bool disableNew;            // disallow allocations using `new`
+    Sizeok sizeok;              // set when structsize contains valid data
+
     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(Loc loc);
-    bool checkOverlappedFields();
+    d_uns64 size(const Loc &loc);
     bool fill(Loc loc, Expressions *elements, bool ctorinit);
-    static void alignmember(structalign_t salign, unsigned size, unsigned *poffset);
-    static unsigned placeField(unsigned *nextoffset,
-        unsigned memsize, unsigned memalignsize, structalign_t memalign,
-        unsigned *paggsize, unsigned *paggalignsize, bool isunion);
     Type *getType();
-    bool isDeprecated();         // is aggregate deprecated?
-    bool isNested();
-    void makeNested();
+    bool isDeprecated() const;         // is aggregate deprecated?
+    void setDeprecated();
+    bool isNested() const;
     bool isExport() const;
     Dsymbol *searchCtor();
 
-    Prot prot();
+    Visibility visible();
 
     // 'this' type
     Type *handleType() { return type; }
 
+    bool hasInvariant();
+
     // Back end
-    Symbol *stag;               // tag symbol for debug data
-    Symbol *sinit;
+    void *sinit;
 
     AggregateDeclaration *isAggregateDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -163,8 +148,7 @@ public:
 
 struct StructFlags
 {
-    typedef unsigned Type;
-    enum Enum
+    enum Type
     {
         none = 0x0,
         hasPointers = 0x1  // NB: should use noPointers as in ClassFlags
@@ -174,9 +158,17 @@ struct StructFlags
 class StructDeclaration : public AggregateDeclaration
 {
 public:
-    int zeroInit;               // !=0 if initialize with 0 fill
+    bool zeroInit;              // !=0 if initialize with 0 fill
     bool hasIdentityAssign;     // true if has identity opAssign
+    bool hasBlitAssign;         // true if opAssign is a blit
     bool hasIdentityEquals;     // true if has identity opEquals
+    bool hasNoFields;           // has no fields
+    bool hasCopyCtor;           // copy constructor
+    // Even if struct is defined as non-root symbol, some built-in operations
+    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
+    // For those, today TypeInfo_Struct is generated in COMDAT.
+    bool requestTypeInfo;
+
     FuncDeclarations postblits; // Array of postblit functions
     FuncDeclaration *postblit;  // aggregate postblit
 
@@ -187,36 +179,30 @@ public:
     static FuncDeclaration *xerrcmp;     // object.xopCmp
 
     structalign_t alignment;    // alignment applied outside of the struct
-    StructPOD ispod;            // if struct is POD
+    ThreeState ispod;           // if struct is POD
 
-    // For 64 bit Efl function call/return ABI
-    Type *arg1type;
-    Type *arg2type;
+    // ABI-specific type(s) if the struct can be passed in registers
+    TypeTuple *argTypes;
 
-    // Even if struct is defined as non-root symbol, some built-in operations
-    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
-    // For those, today TypeInfo_Struct is generated in COMDAT.
-    bool requestTypeInfo;
-
-    StructDeclaration(Loc loc, Identifier *id, bool inObject);
     static StructDeclaration *create(Loc loc, Identifier *id, bool inObject);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semanticTypeInfoMembers();
+    StructDeclaration *syntaxCopy(Dsymbol *s);
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
     const char *kind() const;
     void finalizeSize();
-    bool fit(Loc loc, Scope *sc, Expressions *elements, Type *stype);
     bool isPOD();
 
     StructDeclaration *isStructDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
+
+    unsigned numArgTypes() const;
+    Type *argType(unsigned index);
+    bool hasRegularCtor(bool checkDisabled = false);
 };
 
 class UnionDeclaration : public StructDeclaration
 {
 public:
-    UnionDeclaration(Loc loc, Identifier *id);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    UnionDeclaration *syntaxCopy(Dsymbol *s);
     const char *kind() const;
 
     UnionDeclaration *isUnionDeclaration() { return this; }
@@ -236,18 +222,14 @@ struct BaseClass
     DArray<BaseClass> baseInterfaces;   // if BaseClass is an interface, these
                                         // are a copy of the InterfaceDeclaration::interfaces
 
-    BaseClass();
-    BaseClass(Type *type);
-
     bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance);
-    void copyBaseInterfaces(BaseClasses *);
 };
 
 struct ClassFlags
 {
-    typedef unsigned Type;
-    enum Enum
+    enum Type
     {
+        none = 0x0,
         isCOMclass = 0x1,
         noPointers = 0x2,
         hasOffTi = 0x4,
@@ -286,15 +268,18 @@ public:
 
     TypeInfoClassDeclaration *vclassinfo;       // the ClassInfo object for this ClassDeclaration
     bool com;                           // true if this is a COM class (meaning it derives from IUnknown)
-    bool isscope;                       // true if this is a scope class
-    Abstract isabstract;                // 0: fwdref, 1: is abstract class, 2: not abstract
-    int inuse;                          // to prevent recursive attempts
+    bool stack;                         // true if this is a scope class
+    int cppDtorVtblIndex;               // slot reserved for the virtual destructor [extern(C++)]
+    bool inuse;                         // to prevent recursive attempts
+
+    ThreeState isabstract;              // if abstract class
     Baseok baseok;                      // set the progress of base classes resolving
+    ObjcClassDeclaration objc;          // Data for a class declaration that is needed for the Objective-C integration
     Symbol *cpp_type_info_ptr_sym;      // cached instance of class Id.cpp_type_info_ptr
 
-    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject = false);
     static ClassDeclaration *create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    const char *toPrettyChars(bool QualifyTypes = false);
+    ClassDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
     bool isBaseOf2(ClassDeclaration *cd);
 
@@ -318,9 +303,11 @@ public:
     const char *kind() const;
 
     void addLocalClass(ClassDeclarations *);
+    void addObjcSymbols(ClassDeclarations *classes, ClassDeclarations *categories);
 
     // Back end
-    Symbol *vtblsym;
+    Dsymbol *vtblsym;
+    Dsymbol *vtblSymbol();
 
     ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -329,11 +316,9 @@ public:
 class InterfaceDeclaration : public ClassDeclaration
 {
 public:
-    InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    InterfaceDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
     bool isBaseOf(ClassDeclaration *cd, int *poffset);
-    bool isBaseOf(BaseClass *bc, int *poffset);
     const char *kind() const;
     int vtblOffset() const;
     bool isCPPinterface() const;
diff --git a/gcc/d/dmd/aliasthis.h b/gcc/d/dmd/aliasthis.h
index 15905e41710..de93a8e6ae4 100644
--- a/gcc/d/dmd/aliasthis.h
+++ b/gcc/d/dmd/aliasthis.h
@@ -5,11 +5,12 @@
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/dlang/dmd/blob/master/src/aliasthis.h
+ * https://github.com/dlang/dmd/blob/master/src/dmd/aliasthis.h
  */
 
 #pragma once
 
+#include "globals.h"
 #include "dsymbol.h"
 
 /**************************************************************/
@@ -19,11 +20,12 @@ class AliasThis : public Dsymbol
 public:
    // alias Identifier this;
     Identifier *ident;
+    Dsymbol    *sym;
+    bool       isDeprecated_;
 
-    AliasThis(Loc loc, Identifier *ident);
-
-    Dsymbol *syntaxCopy(Dsymbol *);
+    AliasThis *syntaxCopy(Dsymbol *);
     const char *kind() const;
     AliasThis *isAliasThis() { return this; }
     void accept(Visitor *v) { v->visit(this); }
+    bool isDeprecated() const { return this->isDeprecated_; }
 };
diff --git a/gcc/d/dmd/arraytypes.h b/gcc/d/dmd/arraytypes.h
index 0ecccf170bd..602d89059a0 100644
--- a/gcc/d/dmd/arraytypes.h
+++ b/gcc/d/dmd/arraytypes.h
@@ -27,6 +27,8 @@ typedef Array<class Dsymbol *> Dsymbols;
 
 typedef Array<class RootObject *> Objects;
 
+typedef Array<class DtorDeclaration *> DtorDeclarations;
+
 typedef Array<class FuncDeclaration *> FuncDeclarations;
 
 typedef Array<class Parameter *> Parameters;
@@ -48,8 +50,6 @@ typedef Array<class AliasDeclaration *> AliasDeclarations;
 
 typedef Array<class Module *> Modules;
 
-typedef Array<struct File *> Files;
-
 typedef Array<class CaseStatement *> CaseStatements;
 
 typedef Array<class ScopeStatement *> ScopeStatements;
@@ -63,3 +63,8 @@ typedef Array<class GotoStatement *> GotoStatements;
 typedef Array<class TemplateInstance *> TemplateInstances;
 
 typedef Array<struct Ensure> Ensures;
+
+typedef Array<struct Designator> Designators;
+
+typedef Array<struct DesigInit> DesigInits;
+
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index 174d3c1ad5b..e63c80be3c6 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -10,13 +10,10 @@
 
 #pragma once
 
+#include "root/port.h"
 #include "dsymbol.h"
 
 class Expression;
-class Statement;
-class LabelDsymbol;
-class Initializer;
-class Module;
 class Condition;
 class StaticForeach;
 
@@ -27,12 +24,7 @@ class AttribDeclaration : public Dsymbol
 public:
     Dsymbols *decl;     // array of Dsymbol's
 
-    AttribDeclaration(Dsymbols *decl);
     virtual Dsymbols *include(Scope *sc);
-    int apply(Dsymbol_apply_ft_t fp, void *param);
-    static Scope *createNewScope(Scope *sc,
-        StorageClass newstc, LINK linkage, CPPMANGLE cppmangle, Prot protection,
-        int explicitProtection, AlignDeclaration *aligndecl, PINLINE inlining);
     virtual Scope *newScope(Scope *sc);
     void addMember(Scope *sc, ScopeDsymbol *sds);
     void setScope(Scope *sc);
@@ -40,7 +32,7 @@ public:
     void addComment(const utf8_t *comment);
     const char *kind() const;
     bool oneMember(Dsymbol **ps, Identifier *ident);
-    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
+    void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
     bool hasPointers();
     bool hasStaticCtorOrDtor();
     void checkCtorConstInit();
@@ -55,8 +47,7 @@ class StorageClassDeclaration : public AttribDeclaration
 public:
     StorageClass stc;
 
-    StorageClassDeclaration(StorageClass stc, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    StorageClassDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
     bool oneMember(Dsymbol **ps, Identifier *ident);
     void addMember(Scope *sc, ScopeDsymbol *sds);
@@ -71,11 +62,9 @@ public:
     Expression *msg;
     const char *msgstr;
 
-    DeprecatedDeclaration(Expression *msg, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    DeprecatedDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
     void setScope(Scope *sc);
-    const char *getMessage();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -84,11 +73,10 @@ class LinkDeclaration : public AttribDeclaration
 public:
     LINK linkage;
 
-    LinkDeclaration(LINK p, Dsymbols *decl);
-    static LinkDeclaration *create(LINK p, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    static LinkDeclaration *create(const Loc &loc, LINK p, Dsymbols *decl);
+    LinkDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
-    const char *toChars();
+    const char *toChars() const;
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -97,40 +85,48 @@ class CPPMangleDeclaration : public AttribDeclaration
 public:
     CPPMANGLE cppmangle;
 
-    CPPMangleDeclaration(CPPMANGLE p, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    CPPMangleDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
-    const char *toChars();
+    void setScope(Scope *sc);
+    const char *toChars() const;
     void accept(Visitor *v) { v->visit(this); }
 };
 
-class ProtDeclaration : public AttribDeclaration
+class CPPNamespaceDeclaration : public AttribDeclaration
 {
 public:
-    Prot protection;
-    Identifiers* pkg_identifiers;
+    Expression *exp;
 
-    ProtDeclaration(Loc loc, Prot p, Dsymbols *decl);
-    ProtDeclaration(Loc loc, Identifiers* pkg_identifiers, Dsymbols *decl);
+    CPPNamespaceDeclaration *syntaxCopy(Dsymbol *s);
+    Scope *newScope(Scope *sc);
+    const char *toChars() const;
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+class VisibilityDeclaration : public AttribDeclaration
+{
+public:
+    Visibility visibility;
+    DArray<Identifier*> pkg_identifiers;
 
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    VisibilityDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
     void addMember(Scope *sc, ScopeDsymbol *sds);
     const char *kind() const;
     const char *toPrettyChars(bool unused);
+    VisibilityDeclaration *isVisibilityDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class AlignDeclaration : public AttribDeclaration
 {
 public:
-    Expression *ealign;
+    Expressions *alignExps;
     structalign_t salign;
 
-    AlignDeclaration(Loc loc, Expression *ealign, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    AlignDeclaration(const Loc &loc, Expression *ealign, Dsymbols *decl);
+    AlignDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
-    structalign_t getAlignment(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -143,10 +139,9 @@ public:
     unsigned anonstructsize;    // size of anonymous struct
     unsigned anonalignsize;     // size of anonymous struct for alignment purposes
 
-    AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    AnonDeclaration *syntaxCopy(Dsymbol *s);
     void setScope(Scope *sc);
-    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
+    void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
     const char *kind() const;
     AnonDeclaration *isAnonDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -157,9 +152,9 @@ class PragmaDeclaration : public AttribDeclaration
 public:
     Expressions *args;          // array of Expression's
 
-    PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    PragmaDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
+    PINLINE evalPragmaInline(Scope* sc);
     const char *kind() const;
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -170,8 +165,7 @@ public:
     Condition *condition;
     Dsymbols *elsedecl; // array of Dsymbol's for else block
 
-    ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    ConditionalDeclaration *syntaxCopy(Dsymbol *s);
     bool oneMember(Dsymbol **ps, Identifier *ident);
     Dsymbols *include(Scope *sc);
     void addComment(const utf8_t *comment);
@@ -186,8 +180,7 @@ public:
     bool addisdone;
     bool onStack;
 
-    StaticIfDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    StaticIfDeclaration *syntaxCopy(Dsymbol *s);
     Dsymbols *include(Scope *sc);
     void addMember(Scope *sc, ScopeDsymbol *sds);
     void setScope(Scope *sc);
@@ -205,8 +198,7 @@ public:
     bool cached;
     Dsymbols *cache;
 
-    StaticForeachDeclaration(StaticForeach *sfe, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    StaticForeachDeclaration *syntaxCopy(Dsymbol *s);
     bool oneMember(Dsymbol **ps, Identifier *ident);
     Dsymbols *include(Scope *sc);
     void addMember(Scope *sc, ScopeDsymbol *sds);
@@ -222,7 +214,6 @@ class ForwardingAttribDeclaration : public AttribDeclaration
 public:
     ForwardingScopeDsymbol *sym;
 
-    ForwardingAttribDeclaration(Dsymbols *decl);
     Scope *newScope(Scope *sc);
     void addMember(Scope *sc, ScopeDsymbol *sds);
     ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return this; }
@@ -239,8 +230,7 @@ public:
     ScopeDsymbol *scopesym;
     bool compiled;
 
-    CompileDeclaration(Loc loc, Expressions *exps);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    CompileDeclaration *syntaxCopy(Dsymbol *s);
     void addMember(Scope *sc, ScopeDsymbol *sds);
     void setScope(Scope *sc);
     const char *kind() const;
@@ -256,11 +246,9 @@ class UserAttributeDeclaration : public AttribDeclaration
 public:
     Expressions *atts;
 
-    UserAttributeDeclaration(Expressions *atts, Dsymbols *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    UserAttributeDeclaration *syntaxCopy(Dsymbol *s);
     Scope *newScope(Scope *sc);
     void setScope(Scope *sc);
-    static Expressions *concat(Expressions *udas1, Expressions *udas2);
     Expressions *getAttributes();
     const char *kind() const;
     void accept(Visitor *v) { v->visit(this); }
diff --git a/gcc/d/dmd/compiler.h b/gcc/d/dmd/compiler.h
index e7ef5a4ccf7..27e87b692a8 100644
--- a/gcc/d/dmd/compiler.h
+++ b/gcc/d/dmd/compiler.h
@@ -22,11 +22,6 @@ class Type;
 struct Scope;
 struct UnionExp;
 
-// DMD-generated module `__entrypoint` where the C main resides
-extern Module *entrypoint;
-// Module in which the D main is
-extern Module *rootHasMain;
-
 extern bool includeImports;
 // array of module patterns used to include/exclude imported modules
 extern Array<const char*> includeModulePatterns;
@@ -37,7 +32,6 @@ struct Compiler
     // CTFE support for cross-compilation.
     static Expression *paintAsType(UnionExp *, Expression *, Type *);
     // Backend
-    static void genCmain(Scope *);
     static bool onImport(Module *);
     static void onParseModule(Module *);
 };
diff --git a/gcc/d/dmd/complex_t.h b/gcc/d/dmd/complex_t.h
index 7f174606422..335917135c2 100644
--- a/gcc/d/dmd/complex_t.h
+++ b/gcc/d/dmd/complex_t.h
@@ -20,7 +20,7 @@ struct complex_t
     real_t re;
     real_t im;
 
-    complex_t(real_t re) : re(re), im(ldouble(0)) {}
+    complex_t(real_t re) : re(re), im(CTFloat::zero) {}
     complex_t(real_t re, real_t im) : re(re), im(im) {}
 
     complex_t operator + (complex_t y) { return complex_t(re + y.re, im + y.im); }
@@ -52,7 +52,7 @@ struct complex_t
     int operator != (complex_t y) { return re != y.re || im != y.im; }
 
 private:
-    complex_t() : re(ldouble(0)), im(ldouble(0)) {}
+    complex_t() : re(CTFloat::zero), im(CTFloat::zero) {}
 };
 
 inline complex_t operator * (real_t x, complex_t y) { return complex_t(x) * y; }
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index 593a98d10b4..4f261162ebb 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -16,26 +16,24 @@
 
 class Expression;
 class Identifier;
-struct OutBuffer;
 class Module;
 struct Scope;
-class ScopeDsymbol;
 class DebugCondition;
 class ForeachStatement;
 class ForeachRangeStatement;
 
-int findCondition(Identifiers *ids, Identifier *ident);
+enum Include
+{
+    INCLUDEnotComputed, /// not computed yet
+    INCLUDEyes,         /// include the conditional code
+    INCLUDEno           /// do not include the conditional code
+};
 
 class Condition : public ASTNode
 {
 public:
     Loc loc;
-    // 0: not computed yet
-    // 1: include
-    // 2: do not include
-    int inc;
-
-    Condition(Loc loc);
+    Include inc;
 
     virtual Condition *syntaxCopy() = 0;
     virtual int include(Scope *sc) = 0;
@@ -54,13 +52,9 @@ public:
 
     bool needExpansion;
 
-    StaticForeach(Loc loc, ForeachStatement *aggrfe, ForeachRangeStatement *rangefe);
     StaticForeach *syntaxCopy();
 };
 
-void staticForeachPrepare(StaticForeach *sfe, Scope *sc);
-bool staticForeachReady(StaticForeach *sfe);
-
 class DVCondition : public Condition
 {
 public:
@@ -68,9 +62,7 @@ public:
     Identifier *ident;
     Module *mod;
 
-    DVCondition(Module *mod, unsigned level, Identifier *ident);
-
-    Condition *syntaxCopy();
+    DVCondition *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -79,8 +71,6 @@ class DebugCondition : public DVCondition
 public:
     static void addGlobalIdent(const char *ident);
 
-    DebugCondition(Module *mod, unsigned level, Identifier *ident);
-
     int include(Scope *sc);
     DebugCondition *isDebugCondition() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -92,8 +82,6 @@ public:
     static void addGlobalIdent(const char *ident);
     static void addPredefinedGlobalIdent(const char *ident);
 
-    VersionCondition(Module *mod, unsigned level, Identifier *ident);
-
     int include(Scope *sc);
     VersionCondition *isVersionCondition() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -104,8 +92,7 @@ class StaticIfCondition : public Condition
 public:
     Expression *exp;
 
-    StaticIfCondition(Loc loc, Expression *exp);
-    Condition *syntaxCopy();
+    StaticIfCondition *syntaxCopy();
     int include(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
diff --git a/gcc/d/dmd/ctfe.h b/gcc/d/dmd/ctfe.h
index 359739e24a0..242dd552b94 100644
--- a/gcc/d/dmd/ctfe.h
+++ b/gcc/d/dmd/ctfe.h
@@ -5,30 +5,14 @@
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/dlang/dmd/blob/master/src/ctfe.h
+ * https://github.com/dlang/dmd/blob/master/src/dmd/ctfe.h
  */
 
 #pragma once
 
-#include "arraytypes.h"
 #include "tokens.h"
 #include "expression.h"
 
-/**
-   Global status of the CTFE engine. Mostly used for performance diagnostics
- */
-struct CtfeStatus
-{
-    static int callDepth; // current number of recursive calls
-    /* When printing a stack trace,
-     * suppress this number of calls
-     */
-    static int stackTraceCallsToSuppress;
-    static int maxCallDepth; // highest number of recursive calls
-    static int numArrayAllocs; // Number of allocated arrays
-    static int numAssignments; // total number of assignments executed
-};
-
 /**
   A reference to a class, or an interface. We need this when we
   point to a base class (we must record what the type is).
@@ -37,55 +21,35 @@ class ClassReferenceExp : public Expression
 {
 public:
     StructLiteralExp *value;
-    ClassReferenceExp(Loc loc, StructLiteralExp *lit, Type *type);
     ClassDeclaration *originalClass();
 
-    /// Return index of the field, or -1 if not found
-    int getFieldIndex(Type *fieldtype, unsigned fieldoffset);
     /// Return index of the field, or -1 if not found
     /// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
     int findFieldIndexByName(VarDeclaration *v);
     void accept(Visitor *v) { v->visit(this); }
 };
 
-// The various functions are used only to detect compiler CTFE bugs
-Expression *getValue(VarDeclaration *vd);
-bool hasValue(VarDeclaration *vd);
-void setValueNull(VarDeclaration *vd);
-void setValueWithoutChecking(VarDeclaration *vd, Expression *newval);
-void setValue(VarDeclaration *vd, Expression *newval);
-
-/// Return index of the field, or -1 if not found
-/// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
-int findFieldIndexByName(StructDeclaration *sd, VarDeclaration *v);
-
-
-/** An uninitialized value
+/**
+  An uninitialized value
  */
 class VoidInitExp : public Expression
 {
 public:
     VarDeclaration *var;
 
-    VoidInitExp(VarDeclaration *var, Type *type);
-    const char *toChars();
+    const char *toChars() const;
     void accept(Visitor *v) { v->visit(this); }
 };
 
-// Create an appropriate void initializer
-UnionExp voidInitLiteral(Type *t, VarDeclaration *var);
-
-/** Fake class which holds the thrown exception.
-    Used for implementing exception handling.
+/**
+  Fake class which holds the thrown exception.
+  Used for implementing exception handling.
 */
 class ThrownExceptionExp : public Expression
 {
 public:
     ClassReferenceExp *thrown; // the thing being tossed
-    ThrownExceptionExp(Loc loc, ClassReferenceExp *victim);
-    const char *toChars();
-    /// Generate an error message when this exception is not caught
-    void generateUncaughtError();
+    const char *toChars() const;
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -96,173 +60,5 @@ public:
 class CTFEExp : public Expression
 {
 public:
-    CTFEExp(TOK tok);
-
-    const char *toChars();
-
-    // Handy instances to share
-    static CTFEExp *cantexp;
-    static CTFEExp *voidexp;
-    static CTFEExp *breakexp;
-    static CTFEExp *continueexp;
-    static CTFEExp *gotoexp;
-
-    static bool isCantExp(Expression *e) { return e && e->op == TOKcantexp; }
-    static bool isGotoExp(Expression *e) { return e && e->op == TOKgoto; }
+    const char *toChars() const;
 };
-
-/****************************************************************/
-
-
-/// True if 'e' is TOKcantexp, or an exception
-bool exceptionOrCantInterpret(Expression *e);
-
-// Used for debugging only
-void showCtfeExpr(Expression *e, int level = 0);
-
-/// Return true if this is a valid CTFE expression
-bool isCtfeValueValid(Expression *newval);
-bool isCtfeReferenceValid(Expression *newval);
-
-/// Given expr, which evaluates to an array/AA/string literal,
-/// return true if it needs to be copied
-bool needToCopyLiteral(Expression *expr);
-
-/// Make a copy of the ArrayLiteral, AALiteral, String, or StructLiteral.
-/// This value will be used for in-place modification.
-UnionExp copyLiteral(Expression *e);
-
-/// Set this literal to the given type, copying it if necessary
-Expression *paintTypeOntoLiteral(Type *type, Expression *lit);
-Expression *paintTypeOntoLiteral(UnionExp *pue, Type *type, Expression *lit);
-UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit);
-
-/// Convert from a CTFE-internal slice, into a normal Expression
-Expression *resolveSlice(Expression *e, UnionExp *pue = NULL);
-
-/// Determine the array length, without interpreting the expression.
-uinteger_t resolveArrayLength(Expression *e);
-
-/// Create an array literal consisting of 'elem' duplicated 'dim' times.
-ArrayLiteralExp *createBlockDuplicatedArrayLiteral(UnionExp *pue, Loc loc, Type *type,
-        Expression *elem, size_t dim);
-
-/// Create a string literal consisting of 'value' duplicated 'dim' times.
-StringExp *createBlockDuplicatedStringLiteral(UnionExp *pue, Loc loc, Type *type,
-        unsigned value, size_t dim, unsigned char sz);
-
-
-/* Set dest = src, where both dest and src are container value literals
- * (ie, struct literals, or static arrays (can be an array literal or a string)
- * Assignment is recursively in-place.
- * Purpose: any reference to a member of 'dest' will remain valid after the
- * assignment.
- */
-void assignInPlace(Expression *dest, Expression *src);
-
-/// Duplicate the elements array, then set field 'indexToChange' = newelem.
-Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, Expression *newelem);
-
-/// Given an AA literal aae,  set arr[index] = newval and return the new array.
-Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae,
-    Expression *index, Expression *newval);
-
-/// Given array literal oldval of type ArrayLiteralExp or StringExp, of length
-/// oldlen, change its length to newlen. If the newlen is longer than oldlen,
-/// all new elements will be set to the default initializer for the element type.
-UnionExp changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
-    Expression *oldval,  size_t oldlen, size_t newlen);
-
-
-
-/// Return true if t is a pointer (not a function pointer)
-bool isPointer(Type *t);
-
-// For CTFE only. Returns true if 'e' is TRUE or a non-null pointer.
-bool isTrueBool(Expression *e);
-
-/// Is it safe to convert from srcPointee* to destPointee* ?
-///  srcPointee is the genuine type (never void).
-///  destPointee may be void.
-bool isSafePointerCast(Type *srcPointee, Type *destPointee);
-
-/// Given pointer e, return the memory block expression it points to,
-/// and set ofs to the offset within that memory block.
-Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs);
-
-/// Return true if agg1 and agg2 are pointers to the same memory block
-bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2);
-
-// return e1 - e2 as an integer, or error if not possible
-UnionExp pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e2);
-
-/// Return 1 if true, 0 if false
-/// -1 if comparison is illegal because they point to non-comparable memory blocks
-int comparePointers(TOK op, Expression *agg1, dinteger_t ofs1, Expression *agg2, dinteger_t ofs2);
-
-// Return eptr op e2, where eptr is a pointer, e2 is an integer,
-// and op is TOKadd or TOKmin
-UnionExp pointerArithmetic(Loc loc, TOK op, Type *type,
-    Expression *eptr, Expression *e2);
-
-// True if conversion from type 'from' to 'to' involves a reinterpret_cast
-// floating point -> integer or integer -> floating point
-bool isFloatIntPaint(Type *to, Type *from);
-
-// Reinterpret float/int value 'fromVal' as a float/integer of type 'to'.
-Expression *paintFloatInt(UnionExp *pue, Expression *fromVal, Type *to);
-
-/// Return true if t is an AA
-bool isAssocArray(Type *t);
-
-/// Given a template AA type, extract the corresponding built-in AA type
-TypeAArray *toBuiltinAAType(Type *t);
-
-/*  Given an AA literal 'ae', and a key 'e2':
- *  Return ae[e2] if present, or NULL if not found.
- *  Return TOKcantexp on error.
- */
-Expression *findKeyInAA(Loc loc, AssocArrayLiteralExp *ae, Expression *e2);
-
-/// True if type is TypeInfo_Class
-bool isTypeInfo_Class(Type *type);
-
-
-/***********************************************
-      COW const-folding operations
-***********************************************/
-
-/// Return true if non-pointer expression e can be compared
-/// with >,is, ==, etc, using ctfeCmp, ctfeEquals, ctfeIdentity
-bool isCtfeComparable(Expression *e);
-
-/// Evaluate ==, !=.  Resolves slices before comparing. Returns 0 or 1
-int ctfeEqual(Loc loc, TOK op, Expression *e1, Expression *e2);
-
-/// Evaluate is, !is.  Resolves slices before comparing. Returns 0 or 1
-int ctfeIdentity(Loc loc, TOK op, Expression *e1, Expression *e2);
-
-/// Returns rawCmp OP 0; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-int specificCmp(TOK op, int rawCmp);
-
-/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-int intUnsignedCmp(TOK op, dinteger_t n1, dinteger_t n2);
-
-/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-int intSignedCmp(TOK op, sinteger_t n1, sinteger_t n2);
-
-/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
-int realCmp(TOK op, real_t r1, real_t r2);
-
-/// Evaluate >,<=, etc. Resolves slices before comparing. Returns 0 or 1
-int ctfeCmp(Loc loc, TOK op, Expression *e1, Expression *e2);
-
-/// Returns e1 ~ e2. Resolves slices before concatenation.
-UnionExp ctfeCat(Loc loc, Type *type, Expression *e1, Expression *e2);
-
-/// Same as for constfold.Index, except that it only works for static arrays,
-/// dynamic arrays, and strings.
-Expression *ctfeIndex(Loc loc, Type *type, Expression *e1, uinteger_t indx);
-
-/// Cast 'e' of type 'type' to type 'to'.
-Expression *ctfeCast(UnionExp *pue, Loc loc, Type *type, Type *to, Expression *e);
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 55c814288e0..1c56defd3ee 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -13,115 +13,98 @@
 #include "dsymbol.h"
 #include "mtype.h"
 #include "objc.h"
+#include "tokens.h"
 
 class Expression;
 class Statement;
 class LabelDsymbol;
 class Initializer;
-class Module;
 class ForeachStatement;
 struct Ensure
 {
     Identifier *id;
     Statement *ensure;
-
-    Ensure();
-    Ensure(Identifier *id, Statement *ensure);
-    Ensure syntaxCopy();
-    static Ensures *arraySyntaxCopy(Ensures *a);
 };
-class AliasDeclaration;
 class FuncDeclaration;
-class ExpInitializer;
 class StructDeclaration;
-struct InterState;
-struct CompiledCtfeFunction;
-struct ObjcSelector;
 struct IntRange;
 
-enum LINK;
-enum TOK;
-enum MATCH;
-enum PURE;
-enum PINLINE;
-
-#define STCundefined    0LL
-#define STCstatic       1LL
-#define STCextern       2LL
-#define STCconst        4LL
-#define STCfinal        8LL
-#define STCabstract     0x10LL
-#define STCparameter    0x20LL
-#define STCfield        0x40LL
-#define STCoverride     0x80LL
-#define STCauto         0x100LL
-#define STCsynchronized 0x200LL
-#define STCdeprecated   0x400LL
-#define STCin           0x800LL         // in parameter
-#define STCout          0x1000LL        // out parameter
-#define STClazy         0x2000LL        // lazy parameter
-#define STCforeach      0x4000LL        // variable for foreach loop
-#define STCvariadic     0x10000LL       // the 'variadic' parameter in: T foo(T a, U b, V variadic...)
-#define STCctorinit     0x20000LL       // can only be set inside constructor
-#define STCtemplateparameter  0x40000LL // template parameter
-#define STCscope        0x80000LL
-#define STCimmutable    0x100000LL
-#define STCref          0x200000LL
-#define STCinit         0x400000LL      // has explicit initializer
-#define STCmanifest     0x800000LL      // manifest constant
-#define STCnodtor       0x1000000LL     // don't run destructor
-#define STCnothrow      0x2000000LL     // never throws exceptions
-#define STCpure         0x4000000LL     // pure function
-#define STCtls          0x8000000LL     // thread local
-#define STCalias        0x10000000LL    // alias parameter
-#define STCshared       0x20000000LL    // accessible from multiple threads
-// accessible from multiple threads
-// but not typed as "shared"
-#define STCgshared      0x40000000LL
-#define STCwild         0x80000000LL    // for "wild" type constructor
+//enum STC : ulong from astenums.d:
+
+    #define STCundefined          0ULL
+
+    #define STCstatic             1ULL    /// `static`
+    #define STCextern             2ULL    /// `extern`
+    #define STCconst              4ULL    /// `const`
+    #define STCfinal              8ULL    /// `final`
+
+    #define STCabstract           0x10ULL    /// `abstract`
+    #define STCparameter          0x20ULL    /// is function parameter
+    #define STCfield              0x40ULL    /// is field of struct, union or class
+    #define STCoverride           0x80ULL    /// `override`
+
+    #define STCauto               0x100ULL    /// `auto`
+    #define STCsynchronized       0x200ULL    /// `synchronized`
+    #define STCdeprecated         0x400ULL    /// `deprecated`
+    #define STCin                 0x800ULL    /// `in` parameter
+
+    #define STCout                0x1000ULL    /// `out` parameter
+    #define STClazy               0x2000ULL    /// `lazy` parameter
+    #define STCforeach            0x4000ULL    /// variable for foreach loop
+    #define STCvariadic           0x8000ULL    /// the `variadic` parameter in: T foo(T a, U b, V variadic...)
+
+    #define STCctorinit           0x10000ULL    /// can only be set inside constructor
+    #define STCtemplateparameter  0x20000ULL    /// template parameter
+    #define STCref                0x40000ULL    /// `ref`
+    #define STCscope              0x80000ULL    /// `scope`
+
+    #define STCmaybescope         0x100000ULL    /// parameter might be `scope`
+    #define STCscopeinferred      0x200000ULL    /// `scope` has been inferred and should not be part of mangling, `scope` must also be set
+    #define STCreturn             0x400000ULL    /// 'return ref' or 'return scope' for function parameters
+    #define STCreturnScope        0x800000ULL    /// if `ref return scope` then resolve to `ref` and `return scope`
+
+    #define STCreturninferred     0x1000000ULL    /// `return` has been inferred and should not be part of mangling, `return` must also be set
+    #define STCimmutable          0x2000000ULL    /// `immutable`
+    #define STCinit               0x4000000ULL    /// has explicit initializer
+    #define STCmanifest           0x8000000ULL    /// manifest constant
+
+    #define STCnodtor             0x10000000ULL    /// do not run destructor
+    #define STCnothrow            0x20000000ULL    /// `nothrow` meaning never throws exceptions
+    #define STCpure               0x40000000ULL    /// `pure` function
+    #define STCtls                0x80000000ULL    /// thread local
+
+    #define STCalias              0x100000000ULL    /// `alias` parameter
+    #define STCshared             0x200000000ULL    /// accessible from multiple threads
+    #define STCgshared            0x400000000ULL    /// accessible from multiple threads, but not typed as `shared`
+    #define STCwild               0x800000000ULL    /// for wild type constructor
+
+    #define STCproperty           0x1000000000ULL    /// `@property`
+    #define STCsafe               0x2000000000ULL    /// `@safe`
+    #define STCtrusted            0x4000000000ULL    /// `@trusted`
+    #define STCsystem             0x8000000000ULL    /// `@system`
+
+    #define STCctfe               0x10000000000ULL    /// can be used in CTFE, even if it is static
+    #define STCdisable            0x20000000000ULL    /// for functions that are not callable
+    #define STCresult             0x40000000000ULL    /// for result variables passed to out contracts
+    #define STCnodefaultctor      0x80000000000ULL    /// must be set inside constructor
+
+    #define STCtemp               0x100000000000ULL    /// temporary variable
+    #define STCrvalue             0x200000000000ULL    /// force rvalue for variables
+    #define STCnogc               0x400000000000ULL    /// `@nogc`
+    #define STCautoref            0x800000000000ULL    /// Mark for the already deduced `auto ref` parameter
+
+    #define STCinference          0x1000000000000ULL    /// do attribute inference
+    #define STCexptemp            0x2000000000000ULL    /// temporary variable that has lifetime restricted to an expression
+    #define STCfuture             0x4000000000000ULL    /// introducing new base class function
+    #define STClocal              0x8000000000000ULL    /// do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).
+
+    #define STClive               0x10000000000000ULL    /// function `@live` attribute
+    #define STCregister           0x20000000000000ULL    /// `register` storage class (ImportC)
+    #define STCvolatile           0x40000000000000ULL    /// destined for volatile in the back end
+
 #define STC_TYPECTOR    (STCconst | STCimmutable | STCshared | STCwild)
 #define STC_FUNCATTR    (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem)
 
-#define STCproperty      0x100000000LL
-#define STCsafe          0x200000000LL
-#define STCtrusted       0x400000000LL
-#define STCsystem        0x800000000LL
-#define STCctfe          0x1000000000LL  // can be used in CTFE, even if it is static
-#define STCdisable       0x2000000000LL  // for functions that are not callable
-#define STCresult        0x4000000000LL  // for result variables passed to out contracts
-#define STCnodefaultctor 0x8000000000LL  // must be set inside constructor
-#define STCtemp          0x10000000000LL // temporary variable
-#define STCrvalue        0x20000000000LL // force rvalue for variables
-#define STCnogc          0x40000000000LL // @nogc
-#define STCvolatile      0x80000000000LL // destined for volatile in the back end
-#define STCreturn        0x100000000000LL // 'return ref' or 'return scope' for function parameters
-#define STCautoref       0x200000000000LL // Mark for the already deduced 'auto ref' parameter
-#define STCinference     0x400000000000LL // do attribute inference
-#define STCexptemp       0x800000000000LL // temporary variable that has lifetime restricted to an expression
-#define STCmaybescope    0x1000000000000LL // parameter might be 'scope'
-#define STCscopeinferred 0x2000000000000LL // 'scope' has been inferred and should not be part of mangling
-#define STCfuture        0x4000000000000LL // introducing new base class function
-#define STClocal         0x8000000000000LL // do not forward (see ddmd.dsymbol.ForwardingScopeDsymbol).
-
-const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal |
-    STCabstract | STCsynchronized | STCdeprecated | STCfuture | STCoverride | STClazy | STCalias |
-    STCout | STCin |
-    STCmanifest | STCimmutable | STCshared | STCwild | STCnothrow | STCnogc | STCpure | STCref | STCtls |
-    STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable | STClocal);
-
-struct Match
-{
-    int count;                  // number of matches found
-    MATCH last;                 // match level of lastf
-    FuncDeclaration *lastf;     // last matching function we found
-    FuncDeclaration *nextf;     // current matching function
-    FuncDeclaration *anyf;      // pick a func, any func, to use for error recovery
-};
-
-void functionResolve(Match *m, Dsymbol *fd, Loc loc, Scope *sc, Objects *tiargs, Type *tthis, Expressions *fargs, const char **pMessage = NULL);
-int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *));
-void aliasSemantic(AliasDeclaration *ds, Scope *sc);
-
 void ObjectNotFound(Identifier *id);
 
 /**************************************************************/
@@ -132,47 +115,45 @@ public:
     Type *type;
     Type *originalType;         // before semantic analysis
     StorageClass storage_class;
-    Prot protection;
+    Visibility visibility;
     LINK linkage;
-    int inuse;                  // used to detect cycles
+    short inuse;                // used to detect cycles
+    uint8_t adFlags;
     DString mangleOverride;     // overridden symbol with pragma(mangle, "...")
 
-    Declaration(Identifier *id);
     const char *kind() const;
-    d_uns64 size(Loc loc);
-    bool checkDisabled(Loc loc, Scope *sc, bool isAliasedDeclaration = false);
-    int checkModify(Loc loc, Scope *sc, Type *t, Expression *e1, int flag);
+    d_uns64 size(const Loc &loc);
 
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
 
-    bool isStatic() { return (storage_class & STCstatic) != 0; }
+    bool isStatic() const { return (storage_class & STCstatic) != 0; }
     virtual bool isDelete();
     virtual bool isDataseg();
     virtual bool isThreadlocal();
     virtual bool isCodeseg() const;
-    bool isCtorinit()     { return (storage_class & STCctorinit) != 0; }
-    bool isFinal()        { return (storage_class & STCfinal) != 0; }
-    bool isAbstract()     { return (storage_class & STCabstract) != 0; }
-    bool isConst()        { return (storage_class & STCconst) != 0; }
-    bool isImmutable()    { return (storage_class & STCimmutable) != 0; }
-    bool isWild()         { return (storage_class & STCwild) != 0; }
-    bool isAuto()         { return (storage_class & STCauto) != 0; }
-    bool isScope()        { return (storage_class & STCscope) != 0; }
-    bool isSynchronized() { return (storage_class & STCsynchronized) != 0; }
-    bool isParameter()    { return (storage_class & STCparameter) != 0; }
-    bool isDeprecated()   { return (storage_class & STCdeprecated) != 0; }
-    bool isDisabled()     { return (storage_class & STCdisable) != 0; }
-    bool isOverride()     { return (storage_class & STCoverride) != 0; }
-    bool isResult()       { return (storage_class & STCresult) != 0; }
-    bool isField()        { return (storage_class & STCfield) != 0; }
-
-    bool isIn()    { return (storage_class & STCin) != 0; }
-    bool isOut()   { return (storage_class & STCout) != 0; }
-    bool isRef()   { return (storage_class & STCref) != 0; }
-
-    bool isFuture() { return (storage_class & STCfuture) != 0; }
-
-    Prot prot();
+    bool isCtorinit() const     { return (storage_class & STCctorinit) != 0; }
+    bool isFinal() const        { return (storage_class & STCfinal) != 0; }
+    virtual bool isAbstract()   { return (storage_class & STCabstract) != 0; }
+    bool isConst() const        { return (storage_class & STCconst) != 0; }
+    bool isImmutable() const    { return (storage_class & STCimmutable) != 0; }
+    bool isWild() const         { return (storage_class & STCwild) != 0; }
+    bool isAuto() const         { return (storage_class & STCauto) != 0; }
+    bool isScope() const        { return (storage_class & STCscope) != 0; }
+    bool isSynchronized() const { return (storage_class & STCsynchronized) != 0; }
+    bool isParameter() const    { return (storage_class & STCparameter) != 0; }
+    bool isDeprecated() const   { return (storage_class & STCdeprecated) != 0; }
+    bool isOverride() const     { return (storage_class & STCoverride) != 0; }
+    bool isResult() const       { return (storage_class & STCresult) != 0; }
+    bool isField() const        { return (storage_class & STCfield) != 0; }
+
+    bool isIn()  const  { return (storage_class & STCin) != 0; }
+    bool isOut() const  { return (storage_class & STCout) != 0; }
+    bool isRef() const  { return (storage_class & STCref) != 0; }
+    bool isReference() const { return (storage_class & (STCref | STCout)) != 0; }
+
+    bool isFuture() const { return (storage_class & STCfuture) != 0; }
+
+    Visibility visible();
 
     Declaration *isDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -188,8 +169,7 @@ public:
 
     TypeTuple *tupletype;       // !=NULL if this is a type tuple
 
-    TupleDeclaration(Loc loc, Identifier *ident, Objects *objects);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    TupleDeclaration *syntaxCopy(Dsymbol *);
     const char *kind() const;
     Type *getType();
     Dsymbol *toAlias2();
@@ -208,16 +188,14 @@ public:
     Dsymbol *overnext;          // next in overload list
     Dsymbol *_import;           // !=NULL if unresolved internal alias for selective import
 
-    AliasDeclaration(Loc loc, Identifier *ident, Type *type);
-    AliasDeclaration(Loc loc, Identifier *ident, Dsymbol *s);
     static AliasDeclaration *create(Loc loc, Identifier *id, Type *type);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    AliasDeclaration *syntaxCopy(Dsymbol *);
     bool overloadInsert(Dsymbol *s);
     const char *kind() const;
     Type *getType();
     Dsymbol *toAlias();
     Dsymbol *toAlias2();
-    bool isOverloadable();
+    bool isOverloadable() const;
 
     AliasDeclaration *isAliasDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -230,16 +208,14 @@ class OverDeclaration : public Declaration
 public:
     Dsymbol *overnext;          // next in overload list
     Dsymbol *aliassym;
-    bool hasOverloads;
 
-    OverDeclaration(Identifier *ident, Dsymbol *s, bool hasOverloads = true);
     const char *kind() const;
-    bool equals(RootObject *o);
+    bool equals(const RootObject *o) const;
     bool overloadInsert(Dsymbol *s);
 
     Dsymbol *toAlias();
     Dsymbol *isUnique();
-    bool isOverloadable();
+    bool isOverloadable() const;
 
     OverDeclaration *isOverDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -251,33 +227,40 @@ class VarDeclaration : public Declaration
 {
 public:
     Initializer *_init;
+    FuncDeclarations nestedrefs; // referenced by these lexically nested functions
+    Dsymbol *aliassym;          // if redone as alias to another symbol
+    VarDeclaration *lastVar;    // Linked list of variables for goto-skips-init detection
+    Expression *edtor;          // if !=NULL, does the destruction of the variable
+    IntRange *range;            // if !NULL, the variable is known to be within the range
+    VarDeclarations *maybes;    // STCmaybescope variables that are assigned to this STCmaybescope variable
+
+    unsigned endlinnum;         // line number of end of scope that this var lives in
     unsigned offset;
     unsigned sequenceNumber;     // order the variables are declared
-    FuncDeclarations nestedrefs; // referenced by these lexically nested functions
-    bool isargptr;              // if parameter that _argptr points to
     structalign_t alignment;
+
+    // When interpreting, these point to the value (NULL if value not determinable)
+    // The index of this variable on the CTFE stack, ~0u if not allocated
+    unsigned ctfeAdrOnStack;
+
+    bool isargptr;              // if parameter that _argptr points to
     bool ctorinit;              // it has been initialized in a ctor
+    bool iscatchvar;            // this is the exception object variable in catch() clause
+    bool isowner;               // this is an Owner, despite it being `scope`
     bool onstack;               // it is a class that was allocated on the stack
     bool mynew;                 // it is a class new'd with custom operator new
-    int canassign;              // it can be assigned to
+    char canassign;             // it can be assigned to
     bool overlapped;            // if it is a field and has overlapping
     bool overlapUnsafe;         // if it is an overlapping field and the overlaps are unsafe
     bool doNotInferScope;       // do not infer 'scope' for this variable
+    bool doNotInferReturn;      // do not infer 'return' for this variable
     unsigned char isdataseg;    // private data for isDataseg
-    Dsymbol *aliassym;          // if redone as alias to another symbol
-    VarDeclaration *lastVar;    // Linked list of variables for goto-skips-init detection
-    unsigned endlinnum;         // line number of end of scope that this var lives in
-
-    // When interpreting, these point to the value (NULL if value not determinable)
-    // The index of this variable on the CTFE stack, -1 if not allocated
-    int ctfeAdrOnStack;
-    Expression *edtor;          // if !=NULL, does the destruction of the variable
-    IntRange *range;            // if !NULL, the variable is known to be within the range
+    bool isArgDtorVar;          // temporary created to handle scope destruction of a function argument
 
-    VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
-    static VarDeclaration *create(Loc loc, Type *t, Identifier *id, Initializer *init);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
+public:
+    static VarDeclaration *create(const Loc &loc, Type *t, Identifier *id, Initializer *init, StorageClass storage_class = STCundefined);
+    VarDeclaration *syntaxCopy(Dsymbol *);
+    void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
     const char *kind() const;
     AggregateDeclaration *isThis();
     bool needThis();
@@ -291,11 +274,7 @@ public:
     bool canTakeAddressOf();
     bool needsScopeDtor();
     bool enclosesLifetimeOf(VarDeclaration *v) const;
-    Expression *callScopeDtor(Scope *sc);
-    Expression *getConstInitializer(bool needFullType = true);
-    Expression *expandInitializer(Loc loc);
     void checkCtorConstInit();
-    bool checkNestedReference(Scope *sc, Loc loc);
     Dsymbol *toAlias();
     // Eliminate need for dynamic_cast
     VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
@@ -304,6 +283,21 @@ public:
 
 /**************************************************************/
 
+class BitFieldDeclaration : public VarDeclaration
+{
+public:
+    Expression *width;
+
+    unsigned fieldWidth;
+    unsigned bitOffset;
+
+    BitFieldDeclaration *syntaxCopy(Dsymbol*);
+    BitFieldDeclaration *isBitFieldDeclaration() { return this; }
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+/**************************************************************/
+
 // This is a shell around a back end symbol
 
 class SymbolDeclaration : public Declaration
@@ -311,8 +305,6 @@ class SymbolDeclaration : public Declaration
 public:
     StructDeclaration *dsym;
 
-    SymbolDeclaration(Loc loc, StructDeclaration *dsym);
-
     // Eliminate need for dynamic_cast
     SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -323,10 +315,9 @@ class TypeInfoDeclaration : public VarDeclaration
 public:
     Type *tinfo;
 
-    TypeInfoDeclaration(Type *tinfo);
     static TypeInfoDeclaration *create(Type *tinfo);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    const char *toChars();
+    TypeInfoDeclaration *syntaxCopy(Dsymbol *);
+    const char *toChars() const;
 
     TypeInfoDeclaration *isTypeInfoDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -335,7 +326,6 @@ public:
 class TypeInfoStructDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoStructDeclaration(Type *tinfo);
     static TypeInfoStructDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -344,7 +334,6 @@ public:
 class TypeInfoClassDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoClassDeclaration(Type *tinfo);
     static TypeInfoClassDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -353,7 +342,6 @@ public:
 class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoInterfaceDeclaration(Type *tinfo);
     static TypeInfoInterfaceDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -362,7 +350,6 @@ public:
 class TypeInfoPointerDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoPointerDeclaration(Type *tinfo);
     static TypeInfoPointerDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -371,7 +358,6 @@ public:
 class TypeInfoArrayDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoArrayDeclaration(Type *tinfo);
     static TypeInfoArrayDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -380,7 +366,6 @@ public:
 class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoStaticArrayDeclaration(Type *tinfo);
     static TypeInfoStaticArrayDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -389,7 +374,6 @@ public:
 class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoAssociativeArrayDeclaration(Type *tinfo);
     static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -398,7 +382,6 @@ public:
 class TypeInfoEnumDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoEnumDeclaration(Type *tinfo);
     static TypeInfoEnumDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -407,7 +390,6 @@ public:
 class TypeInfoFunctionDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoFunctionDeclaration(Type *tinfo);
     static TypeInfoFunctionDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -416,7 +398,6 @@ public:
 class TypeInfoDelegateDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoDelegateDeclaration(Type *tinfo);
     static TypeInfoDelegateDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -425,7 +406,6 @@ public:
 class TypeInfoTupleDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoTupleDeclaration(Type *tinfo);
     static TypeInfoTupleDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -434,7 +414,6 @@ public:
 class TypeInfoConstDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoConstDeclaration(Type *tinfo);
     static TypeInfoConstDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -443,7 +422,6 @@ public:
 class TypeInfoInvariantDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoInvariantDeclaration(Type *tinfo);
     static TypeInfoInvariantDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -452,7 +430,6 @@ public:
 class TypeInfoSharedDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoSharedDeclaration(Type *tinfo);
     static TypeInfoSharedDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -461,7 +438,6 @@ public:
 class TypeInfoWildDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoWildDeclaration(Type *tinfo);
     static TypeInfoWildDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -470,7 +446,6 @@ public:
 class TypeInfoVectorDeclaration : public TypeInfoDeclaration
 {
 public:
-    TypeInfoVectorDeclaration(Type *tinfo);
     static TypeInfoVectorDeclaration *create(Type *tinfo);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -481,13 +456,12 @@ public:
 class ThisDeclaration : public VarDeclaration
 {
 public:
-    ThisDeclaration(Loc loc, Type *t);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    ThisDeclaration *syntaxCopy(Dsymbol *);
     ThisDeclaration *isThisDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
-enum ILS
+enum class ILS : unsigned char
 {
     ILSuninitialized,   // not computed yet
     ILSno,              // cannot inline
@@ -496,68 +470,53 @@ enum ILS
 
 /**************************************************************/
 
-enum BUILTIN
-{
-    BUILTINunknown = 255,   /// not known if this is a builtin
-    BUILTINunimp = 0,       /// this is not a builtin
-    BUILTINgcc,             /// this is a GCC builtin
-    BUILTINllvm,            /// this is an LLVM builtin
-    BUILTINsin,
-    BUILTINcos,
-    BUILTINtan,
-    BUILTINsqrt,
-    BUILTINfabs,
-    BUILTINldexp,
-    BUILTINlog,
-    BUILTINlog2,
-    BUILTINlog10,
-    BUILTINexp,
-    BUILTINexpm1,
-    BUILTINexp2,
-    BUILTINround,
-    BUILTINfloor,
-    BUILTINceil,
-    BUILTINtrunc,
-    BUILTINcopysign,
-    BUILTINpow,
-    BUILTINfmin,
-    BUILTINfmax,
-    BUILTINfma,
-    BUILTINisnan,
-    BUILTINisinfinity,
-    BUILTINisfinite,
-    BUILTINbsf,
-    BUILTINbsr,
-    BUILTINbswap,
-    BUILTINpopcnt,
-    BUILTINyl2x,
-    BUILTINyl2xp1,
-    BUILTINtoPrecFloat,
-    BUILTINtoPrecDouble,
-    BUILTINtoPrecReal
+enum class BUILTIN : unsigned char
+{
+    unknown = 255,   /// not known if this is a builtin
+    unimp = 0,       /// this is not a builtin
+    gcc,             /// this is a GCC builtin
+    llvm,            /// this is an LLVM builtin
+    sin,
+    cos,
+    tan,
+    sqrt,
+    fabs,
+    ldexp,
+    log,
+    log2,
+    log10,
+    exp,
+    expm1,
+    exp2,
+    round,
+    floor,
+    ceil,
+    trunc,
+    copysign,
+    pow,
+    fmin,
+    fmax,
+    fma,
+    isnan,
+    isinfinity,
+    isfinite,
+    bsf,
+    bsr,
+    bswap,
+    popcnt,
+    yl2x,
+    yl2xp1,
+    toPrecFloat,
+    toPrecDouble,
+    toPrecReal
 };
 
 Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments);
 BUILTIN isBuiltin(FuncDeclaration *fd);
 
-typedef Expression *(*builtin_fp)(Loc loc, FuncDeclaration *fd, Expressions *arguments);
-void add_builtin(const char *mangle, builtin_fp fp);
-void builtin_init();
-
-#define FUNCFLAGpurityInprocess    1    // working on determining purity
-#define FUNCFLAGsafetyInprocess    2    // working on determining safety
-#define FUNCFLAGnothrowInprocess   4    // working on determining nothrow
-#define FUNCFLAGnogcInprocess      8    // working on determining @nogc
-#define FUNCFLAGreturnInprocess 0x10    // working on inferring 'return' for parameters
-#define FUNCFLAGinlineScanned   0x20    // function has been scanned for inline possibilities
-#define FUNCFLAGinferScope      0x40    // infer 'scope' for parameters
-#define FUNCFLAGprintf          0x200   // is a printf-like function
-#define FUNCFLAGscanf           0x400   // is a scanf-like function
-
 class FuncDeclaration : public Declaration
 {
 public:
-    Types *fthrows;                     // Array of Type's of exceptions (not used)
     Statements *frequires;              // in contracts
     Ensures *fensures;                  // out contracts
     Statement *frequire;                // lowered in contract
@@ -568,6 +527,9 @@ public:
     FuncDeclaration *fdrequire;         // function that does the in contract
     FuncDeclaration *fdensure;          // function that does the out contract
 
+    Expressions *fdrequireParams;       // argument list for __require
+    Expressions *fdensureParams;        // argument list for __ensure
+
     const char *mangleString;           // mangled symbol created from mangleExact()
 
     VarDeclaration *vresult;            // result variable for out contracts
@@ -577,8 +539,9 @@ public:
     // scopes from having the same name
     DsymbolTable *localsymtab;
     VarDeclaration *vthis;              // 'this' parameter (member and nested)
+    bool isThis2;                       // has a dual-context 'this' parameter
     VarDeclaration *v_arguments;        // '_arguments' parameter
-    ObjcSelector* selector;             // Objective-C method selector (member function only)
+
     VarDeclaration *v_argptr;           // '_argptr' variable
     VarDeclarations *parameters;        // Array of VarDeclaration's for parameters
     DsymbolTable *labtab;               // statement label symbol table
@@ -589,13 +552,16 @@ public:
     bool naked;                         // true if naked
     bool generated;                     // true if function was generated by the compiler rather than
                                         // supplied by the user
+    bool hasAlwaysInlines;              // contains references to functions that must be inlined
+    unsigned char isCrtCtorDtor;        // has attribute pragma(crt_constructor(1)/crt_destructor(2))
+                                        // not set before the glue layer
     ILS inlineStatusStmt;
     ILS inlineStatusExp;
     PINLINE inlining;
 
-    CompiledCtfeFunction *ctfeCode;     // Compiled code for interpreter
     int inlineNest;                     // !=0 if nested inline
-    bool isArrayOp;                     // true if array operation
+    bool eh_none;                       /// true if no exception unwinding is needed
+
     // true if errors in semantic3 this function's frame ptr
     bool semantic3Errors;
     ForeachStatement *fes;              // if foreach body, this is the foreach
@@ -635,6 +601,12 @@ public:
 
     // local variables in this function which are referenced by nested functions
     VarDeclarations closureVars;
+
+    /** Outer variables which are referenced by this nested function
+     * (the inverse of closureVars)
+     */
+    VarDeclarations outerVars;
+
     // Sibling nested functions which called this one
     FuncDeclarations siblingCallers;
 
@@ -642,76 +614,62 @@ public:
 
     unsigned flags;                     // FUNCFLAGxxxxx
 
-    FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
-    static FuncDeclaration *create(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    // Data for a function declaration that is needed for the Objective-C
+    // integration.
+    ObjcFuncDeclaration objc;
+
+    static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false);
+    FuncDeclaration *syntaxCopy(Dsymbol *);
     bool functionSemantic();
     bool functionSemantic3();
-    bool checkForwardRef(Loc loc);
-    // called from semantic3
-    VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad);
-    bool equals(RootObject *o);
+    bool equals(const RootObject *o) const;
 
     int overrides(FuncDeclaration *fd);
-    int findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349 = true);
+    int findVtblIndex(Dsymbols *vtbl, int dim);
     BaseClass *overrideInterface();
     bool overloadInsert(Dsymbol *s);
-    FuncDeclaration *overloadExactMatch(Type *t);
-    FuncDeclaration *overloadModMatch(Loc loc, Type *tthis, bool &hasOverloads);
-    TemplateDeclaration *findTemplateDeclRoot();
     bool inUnittest();
     MATCH leastAsSpecialized(FuncDeclaration *g);
-    LabelDsymbol *searchLabel(Identifier *ident);
-    int getLevel(Loc loc, Scope *sc, FuncDeclaration *fd); // lexical nesting level difference
+    LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc);
+    int getLevel(FuncDeclaration *fd, int intypeof); // lexical nesting level difference
+    int getLevelAndCheck(const Loc &loc, Scope *sc, FuncDeclaration *fd);
     const char *toPrettyChars(bool QualifyTypes = false);
     const char *toFullSignature();  // for diagnostics, e.g. 'int foo(int x, int y) pure'
-    bool isMain();
-    bool isCMain();
-    bool isWinMain();
-    bool isDllMain();
+    bool isMain() const;
+    bool isCMain() const;
+    bool isWinMain() const;
+    bool isDllMain() const;
     bool isExport() const;
     bool isImportedSymbol() const;
     bool isCodeseg() const;
-    bool isOverloadable();
+    bool isOverloadable() const;
+    bool isAbstract();
     PURE isPure();
     PURE isPureBypassingInference();
-    bool setImpure();
     bool isSafe();
     bool isSafeBypassingInference();
     bool isTrusted();
-    bool setUnsafe();
 
     bool isNogc();
     bool isNogcBypassingInference();
-    bool setGC();
 
-    void printGCUsage(Loc loc, const char *warn);
-    bool isolateReturn();
-    bool parametersIntersect(Type *t);
-    virtual bool isNested();
+    virtual bool isNested() const;
     AggregateDeclaration *isThis();
     bool needThis();
     bool isVirtualMethod();
-    virtual bool isVirtual();
-    virtual bool isFinalFunc();
+    virtual bool isVirtual() const;
+    bool isFinalFunc() const;
     virtual bool addPreInvariant();
     virtual bool addPostInvariant();
     const char *kind() const;
-    FuncDeclaration *isUnique();
-    bool checkNestedReference(Scope *sc, Loc loc);
+    bool isUnique();
     bool needsClosure();
-    bool checkClosure();
     bool hasNestedFrameRefs();
-    void buildResultVar(Scope *sc, Type *tret);
-    Statement *mergeFrequire(Statement *);
-    static bool needsFensure(FuncDeclaration *fd);
-    void buildEnsureRequire();
-    Statement *mergeFensure(Statement *, Identifier *oid);
     ParameterList getParameterList();
 
     static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);
     static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);
-    void checkDmain();
+
     bool checkNRVO();
 
     FuncDeclaration *isFuncDeclaration() { return this; }
@@ -720,20 +678,12 @@ public:
     void accept(Visitor *v) { v->visit(this); }
 };
 
-FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
-        Objects *tiargs,
-        Type *tthis,
-        Expressions *arguments,
-        int flags = 0);
-
 class FuncAliasDeclaration : public FuncDeclaration
 {
 public:
     FuncDeclaration *funcalias;
     bool hasOverloads;
 
-    FuncAliasDeclaration(Identifier *ident, FuncDeclaration *funcalias, bool hasOverloads = true);
-
     FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
     const char *kind() const;
 
@@ -750,12 +700,10 @@ public:
     // backend
     bool deferToObj;
 
-    FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, TOK tok,
-        ForeachStatement *fes, Identifier *id = NULL);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    bool isNested();
+    FuncLiteralDeclaration *syntaxCopy(Dsymbol *);
+    bool isNested() const;
     AggregateDeclaration *isThis();
-    bool isVirtual();
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
 
@@ -770,11 +718,11 @@ public:
 class CtorDeclaration : public FuncDeclaration
 {
 public:
-    CtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Type *type);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    bool isCpCtor;
+    CtorDeclaration *syntaxCopy(Dsymbol *);
     const char *kind() const;
-    const char *toChars();
-    bool isVirtual();
+    const char *toChars() const;
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
 
@@ -785,9 +733,8 @@ public:
 class PostBlitDeclaration : public FuncDeclaration
 {
 public:
-    PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    bool isVirtual();
+    PostBlitDeclaration *syntaxCopy(Dsymbol *);
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
     bool overloadInsert(Dsymbol *s);
@@ -799,12 +746,10 @@ public:
 class DtorDeclaration : public FuncDeclaration
 {
 public:
-    DtorDeclaration(Loc loc, Loc endloc);
-    DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    DtorDeclaration *syntaxCopy(Dsymbol *);
     const char *kind() const;
-    const char *toChars();
-    bool isVirtual();
+    const char *toChars() const;
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
     bool overloadInsert(Dsymbol *s);
@@ -816,11 +761,9 @@ public:
 class StaticCtorDeclaration : public FuncDeclaration
 {
 public:
-    StaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
-    StaticCtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    StaticCtorDeclaration *syntaxCopy(Dsymbol *);
     AggregateDeclaration *isThis();
-    bool isVirtual();
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
     bool hasStaticCtorOrDtor();
@@ -832,8 +775,7 @@ public:
 class SharedStaticCtorDeclaration : public StaticCtorDeclaration
 {
 public:
-    SharedStaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *);
 
     SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -844,11 +786,9 @@ class StaticDtorDeclaration : public FuncDeclaration
 public:
     VarDeclaration *vgate;      // 'gate' variable
 
-    StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
-    StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    StaticDtorDeclaration *syntaxCopy(Dsymbol *);
     AggregateDeclaration *isThis();
-    bool isVirtual();
+    bool isVirtual() const;
     bool hasStaticCtorOrDtor();
     bool addPreInvariant();
     bool addPostInvariant();
@@ -860,8 +800,7 @@ public:
 class SharedStaticDtorDeclaration : public StaticDtorDeclaration
 {
 public:
-    SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *);
 
     SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -870,9 +809,8 @@ public:
 class InvariantDeclaration : public FuncDeclaration
 {
 public:
-    InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id = NULL);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    bool isVirtual();
+    InvariantDeclaration *syntaxCopy(Dsymbol *);
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
 
@@ -888,10 +826,9 @@ public:
     // toObjFile() these nested functions after this one
     FuncDeclarations deferredNested;
 
-    UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    UnitTestDeclaration *syntaxCopy(Dsymbol *);
     AggregateDeclaration *isThis();
-    bool isVirtual();
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
 
@@ -905,31 +842,12 @@ public:
     Parameters *parameters;
     VarArg varargs;
 
-    NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, VarArg varargs);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    NewDeclaration *syntaxCopy(Dsymbol *);
     const char *kind() const;
-    bool isVirtual();
+    bool isVirtual() const;
     bool addPreInvariant();
     bool addPostInvariant();
 
     NewDeclaration *isNewDeclaration() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
-
-
-class DeleteDeclaration : public FuncDeclaration
-{
-public:
-    Parameters *parameters;
-
-    DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    const char *kind() const;
-    bool isDelete();
-    bool isVirtual();
-    bool addPreInvariant();
-    bool addPostInvariant();
-
-    DeleteDeclaration *isDeleteDeclaration() { return this; }
-    void accept(Visitor *v) { v->visit(this); }
-};
diff --git a/gcc/d/dmd/doc.h b/gcc/d/dmd/doc.h
index 6d13ab1c121..a144417daee 100644
--- a/gcc/d/dmd/doc.h
+++ b/gcc/d/dmd/doc.h
@@ -5,15 +5,11 @@
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/D-Programming-Language/dmd/blob/master/src/doc.h
+ * https://github.com/dlang/dmd/blob/master/src/dmd/doc.h
  */
 
 #pragma once
 
-#include "root/dsystem.h"
-
 class Module;
-struct OutBuffer;
 
-void escapeDdocString(OutBuffer *buf, size_t start);
 void gendocfile(Module *m);
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index ce0ce4564af..f43bc837992 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -11,17 +11,18 @@
 #pragma once
 
 #include "root/port.h"
-#include "root/stringtable.h"
 #include "ast_node.h"
 #include "globals.h"
 #include "arraytypes.h"
 #include "visitor.h"
 
+class CPPNamespaceDeclaration;
 class Identifier;
 struct Scope;
 class DsymbolTable;
 class Declaration;
 class ThisDeclaration;
+class BitFieldDeclaration;
 class TypeInfoDeclaration;
 class TupleDeclaration;
 class AliasDeclaration;
@@ -47,6 +48,7 @@ class UnitTestDeclaration;
 class NewDeclaration;
 class VarDeclaration;
 class AttribDeclaration;
+class VisibilityDeclaration;
 class Package;
 class Module;
 class Import;
@@ -66,7 +68,8 @@ class WithScopeSymbol;
 class ArrayScopeSymbol;
 class SymbolDeclaration;
 class Expression;
-class DeleteDeclaration;
+class ExpressionDsymbol;
+class AliasAssign;
 class OverloadSet;
 struct AA;
 #ifdef IN_GCC
@@ -84,10 +87,10 @@ struct Ungag
 };
 
 void dsymbolSemantic(Dsymbol *dsym, Scope *sc);
-void semantic2(Dsymbol *dsym, Scope* sc);
+void semantic2(Dsymbol *dsym, Scope *sc);
 void semantic3(Dsymbol *dsym, Scope* sc);
 
-struct Prot
+struct Visibility
 {
     enum Kind
     {
@@ -101,18 +104,8 @@ struct Prot
     };
     Kind kind;
     Package *pkg;
-
-    Prot();
-    Prot(Kind kind);
-
-    bool isMoreRestrictiveThan(const Prot other) const;
-    bool operator==(const Prot& other) const;
 };
 
-// in hdrgen.c
-void protectionToBuffer(OutBuffer *buf, Prot prot);
-const char *protectionToChars(Prot::Kind kind);
-
 /* State of symbol in winding its way through the passes of the compiler
  */
 enum PASS
@@ -143,16 +136,27 @@ enum
                                     // meaning don't search imports in that scope,
                                     // because qualified module searches search
                                     // their imports
-    IgnoreSymbolVisibility  = 0x80  // also find private and package protected symbols
+    IgnoreSymbolVisibility  = 0x80,  // also find private and package protected symbols
+    TagNameSpace            = 0x100, // search ImportC tag symbol table
 };
 
-typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *);
+struct FieldState
+{
+    unsigned offset;
+
+    unsigned fieldOffset;
+    unsigned bitOffset;
+    unsigned fieldSice;
+    bool inFlight;
+};
 
 class Dsymbol : public ASTNode
 {
 public:
     Identifier *ident;
     Dsymbol *parent;
+    /// C++ namespace this symbol belongs to
+    CPPNamespaceDeclaration *namespace_;
     Symbol *csym;               // symbol for code generator
     Symbol *isym;               // import version of csym
     const utf8_t *comment;      // documentation comment for this Dsymbol
@@ -161,74 +165,72 @@ public:
     const utf8_t *prettystring;
     bool errors;                // this symbol failed to pass semantic()
     PASS semanticRun;
+    unsigned short localNum;        // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab
     DeprecatedDeclaration *depdecl; // customized deprecation message
     UserAttributeDeclaration *userAttribDecl;   // user defined attributes
     UnitTestDeclaration *ddocUnittest; // !=NULL means there's a ddoc unittest associated with this symbol (only use this with ddoc)
 
-    Dsymbol();
-    Dsymbol(Identifier *);
     static Dsymbol *create(Identifier *);
-    const char *toChars();
+    const char *toChars() const;
     virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments
-    Loc& getLoc();
+    Loc getLoc();
     const char *locToChars();
-    bool equals(RootObject *o);
-    bool isAnonymous();
-    void error(Loc loc, const char *format, ...);
+    bool equals(const RootObject *o) const;
+    bool isAnonymous() const;
+    void error(const Loc &loc, const char *format, ...);
     void error(const char *format, ...);
-    void deprecation(Loc loc, const char *format, ...);
+    void deprecation(const Loc &loc, const char *format, ...);
     void deprecation(const char *format, ...);
-    bool checkDeprecated(Loc loc, Scope *sc);
+    bool checkDeprecated(const Loc &loc, Scope *sc);
     Module *getModule();
     Module *getAccessModule();
     Dsymbol *pastMixin();
-    Dsymbol *pastMixinAndNspace();
     Dsymbol *toParent();
     Dsymbol *toParent2();
-    Dsymbol *toParent3();
+    Dsymbol *toParentDecl();
+    Dsymbol *toParentLocal();
+    Dsymbol *toParentP(Dsymbol *p1, Dsymbol *p2 = NULL);
     TemplateInstance *isInstantiated();
+    bool followInstantiationContext(Dsymbol *p1, Dsymbol *p2 = NULL);
     TemplateInstance *isSpeculative();
     Ungag ungagSpeculative();
 
     // kludge for template.isSymbol()
-    int dyncast() const { return DYNCAST_DSYMBOL; }
-
-    static Dsymbols *arraySyntaxCopy(Dsymbols *a);
+    DYNCAST dyncast() const { return DYNCAST_DSYMBOL; }
 
     virtual Identifier *getIdent();
     virtual const char *toPrettyChars(bool QualifyTypes = false);
     virtual const char *kind() const;
     virtual Dsymbol *toAlias();                 // resolve real symbol
     virtual Dsymbol *toAlias2();
-    virtual int apply(Dsymbol_apply_ft_t fp, void *param);
     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, int flags = IgnoreNone);
-    Dsymbol *search_correct(Identifier *id);
-    Dsymbol *searchX(Loc loc, Scope *sc, RootObject *id, int flags);
     virtual bool overloadInsert(Dsymbol *s);
-    virtual d_uns64 size(Loc loc);
+    virtual d_uns64 size(const Loc &loc);
     virtual bool isforwardRef();
     virtual AggregateDeclaration *isThis();     // is a 'this' required to access the member
     virtual bool isExport() const;              // is Dsymbol exported?
     virtual bool isImportedSymbol() const;      // is Dsymbol imported?
-    virtual bool isDeprecated();                // is Dsymbol deprecated?
-    virtual bool isOverloadable();
+    virtual bool isDeprecated() const;                // is Dsymbol deprecated?
+    virtual bool isOverloadable() const;
     virtual LabelDsymbol *isLabel();            // is this a LabelDsymbol?
-    AggregateDeclaration *isMember();           // is this a member of an AggregateDeclaration?
-    AggregateDeclaration *isMember2();          // is this a member of an AggregateDeclaration?
-    ClassDeclaration *isClassMember();          // is this a member of a ClassDeclaration?
+    AggregateDeclaration *isMember();           // is toParent() an AggregateDeclaration?
+    AggregateDeclaration *isMember2();          // is toParent2() an AggregateDeclaration?
+    AggregateDeclaration *isMemberDecl();       // is toParentDecl() an AggregateDeclaration?
+    AggregateDeclaration *isMemberLocal();      // is toParentLocal() an AggregateDeclaration?
+    ClassDeclaration *isClassMember();          // isMember() is a ClassDeclaration?
     virtual Type *getType();                    // is this a type?
     virtual bool needThis();                    // need a 'this' pointer?
-    virtual Prot prot();
+    virtual Visibility visible();
     virtual Dsymbol *syntaxCopy(Dsymbol *s);    // copy only syntax trees
     virtual bool oneMember(Dsymbol **ps, Identifier *ident);
-    static bool oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident);
-    virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
+    virtual void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
     virtual bool hasPointers();
     virtual bool hasStaticCtorOrDtor();
     virtual void addLocalClass(ClassDeclarations *) { }
+    virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { }
     virtual void checkCtorConstInit() { }
 
     virtual void addComment(const utf8_t *comment);
@@ -246,7 +248,10 @@ public:
     virtual Nspace *isNspace() { return NULL; }
     virtual Declaration *isDeclaration() { return NULL; }
     virtual StorageClassDeclaration *isStorageClassDeclaration(){ return NULL; }
+    virtual ExpressionDsymbol *isExpressionDsymbol() { return NULL; }
+    virtual AliasAssign *isAliasAssign() { return NULL; }
     virtual ThisDeclaration *isThisDeclaration() { return NULL; }
+    virtual BitFieldDeclaration *isBitFieldDeclaration() { return NULL; }
     virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; }
     virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
     virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
@@ -278,11 +283,13 @@ public:
     virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
     virtual Import *isImport() { return NULL; }
     virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
-    virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
     virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; }
     virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
     virtual AnonDeclaration *isAnonDeclaration() { return NULL; }
+    virtual CPPNamespaceDeclaration *isCPPNamespaceDeclaration() { return NULL; }
+    virtual VisibilityDeclaration *isVisibilityDeclaration() { return NULL; }
     virtual OverloadSet *isOverloadSet() { return NULL; }
+    virtual CompileDeclaration *isCompileDeclaration() { return NULL; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -297,30 +304,23 @@ public:
 
 private:
     Dsymbols *importedScopes;   // imported Dsymbol's
-    Prot::Kind *prots;            // array of PROTKIND, one for each import
+    Visibility::Kind *visibilities;   // array of `Visibility.Kind`, one for each import
 
     BitArray accessiblePackages, privateAccessiblePackages;
 
 public:
-    ScopeDsymbol();
-    ScopeDsymbol(Identifier *id);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    ScopeDsymbol *syntaxCopy(Dsymbol *s);
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
-    OverloadSet *mergeOverloadSet(Identifier *ident, OverloadSet *os, Dsymbol *s);
-    virtual void importScope(Dsymbol *s, Prot protection);
-    void addAccessiblePackage(Package *p, Prot protection);
-    virtual bool isPackageAccessible(Package *p, Prot protection, int flags = 0);
+    virtual void importScope(Dsymbol *s, Visibility visibility);
+    virtual bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0);
     bool isforwardRef();
-    static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
+    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();
 
-    static size_t dim(Dsymbols *members);
-    static Dsymbol *getNth(Dsymbols *members, size_t nth, size_t *pn = NULL);
-
     ScopeDsymbol *isScopeDsymbol() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -332,7 +332,6 @@ class WithScopeSymbol : public ScopeDsymbol
 public:
     WithStatement *withstate;
 
-    WithScopeSymbol(WithStatement *withstate);
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
 
     WithScopeSymbol *isWithScopeSymbol() { return this; }
@@ -343,15 +342,11 @@ public:
 
 class ArrayScopeSymbol : public ScopeDsymbol
 {
+private:
+    RootObject *arrayContent;
 public:
-    Expression *exp;    // IndexExp or SliceExp
-    TypeTuple *type;    // for tuple[length]
-    TupleDeclaration *td;       // for tuples of objects
     Scope *sc;
 
-    ArrayScopeSymbol(Scope *sc, Expression *e);
-    ArrayScopeSymbol(Scope *sc, TypeTuple *t);
-    ArrayScopeSymbol(Scope *sc, TupleDeclaration *td);
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone);
 
     ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
@@ -365,7 +360,6 @@ class OverloadSet : public Dsymbol
 public:
     Dsymbols a;         // array of Dsymbols
 
-    OverloadSet(Identifier *ident, OverloadSet *os = NULL);
     void push(Dsymbol *s);
     OverloadSet *isOverloadSet() { return this; }
     const char *kind() const;
@@ -379,15 +373,22 @@ class ForwardingScopeDsymbol : public ScopeDsymbol
 public:
     ScopeDsymbol *forward;
 
-    ForwardingScopeDsymbol(ScopeDsymbol *forward);
     Dsymbol *symtabInsert(Dsymbol *s);
     Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);
-    void importScope(Dsymbol *s, Prot protection);
+    void importScope(Dsymbol *s, Visibility visibility);
     const char *kind() const;
 
     ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; }
 };
 
+class ExpressionDsymbol : public Dsymbol
+{
+public:
+    Expression *exp;
+
+    ExpressionDsymbol *isExpressionDsymbol() { return this; }
+};
+
 // Table of Dsymbol's
 
 class DsymbolTable : public RootObject
@@ -395,15 +396,16 @@ class DsymbolTable : public RootObject
 public:
     AA *tab;
 
-    DsymbolTable();
-
     // Look up Identifier. Return Dsymbol if found, NULL if not.
     Dsymbol *lookup(Identifier const * const ident);
 
+    // Look for Dsymbol in table. If there, return it. If not, insert s and return that.
+    void update(Dsymbol *s);
+
     // Insert Dsymbol in table. Return NULL if already there.
     Dsymbol *insert(Dsymbol *s);
-
-    // Look for Dsymbol in table. If there, return it. If not, insert s and return that.
-    Dsymbol *update(Dsymbol *s);
     Dsymbol *insert(Identifier const * const ident, Dsymbol *s);     // when ident and s are not the same
+
+    // Number of symbols in symbol table
+    size_t length() const;
 };
diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h
index ae5ea214a73..76c1235715b 100644
--- a/gcc/d/dmd/enum.h
+++ b/gcc/d/dmd/enum.h
@@ -10,15 +10,12 @@
 
 #pragma once
 
-#include "root/root.h"
 #include "dsymbol.h"
 #include "declaration.h"
-#include "tokens.h"
 
 class Identifier;
 class Type;
 class Expression;
-class VarDeclaration;
 
 class EnumDeclaration : public ScopeDsymbol
 {
@@ -33,7 +30,7 @@ public:
      */
     Type *type;                 // the TypeEnum
     Type *memtype;              // type of the members
-    Prot protection;
+    Visibility visibility;
 
     Expression *maxval;
     Expression *minval;
@@ -43,20 +40,18 @@ public:
     bool added;
     int inuse;
 
-    EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    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, int flags = SearchLocalsOnly);
-    bool isDeprecated();                // is Dsymbol deprecated?
-    Prot prot();
-    Expression *getMaxMinValue(Loc loc, Identifier *id);
+    bool isDeprecated() const;                // is Dsymbol deprecated?
+    Visibility visible();
     bool isSpecial() const;
-    Expression *getDefaultValue(Loc loc);
-    Type *getMemtype(Loc loc);
+    Expression *getDefaultValue(const Loc &loc);
+    Type *getMemtype(const Loc &loc);
 
     EnumDeclaration *isEnumDeclaration() { return this; }
 
@@ -83,12 +78,8 @@ public:
 
     EnumDeclaration *ed;
 
-    EnumMember(Loc loc, Identifier *id, Expression *value, Type *origType);
-    EnumMember(Loc loc, Identifier *id, Expression *value, Type *memType,
-        StorageClass stc, UserAttributeDeclaration *uad, DeprecatedDeclaration *dd);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    EnumMember *syntaxCopy(Dsymbol *s);
     const char *kind() const;
-    Expression *getVarExp(Loc loc, Scope *sc);
 
     EnumMember *isEnumMember() { return this; }
     void accept(Visitor *v) { v->visit(this); }
diff --git a/gcc/d/dmd/errors.h b/gcc/d/dmd/errors.h
index a92ae2abbc4..6d9587d1436 100644
--- a/gcc/d/dmd/errors.h
+++ b/gcc/d/dmd/errors.h
@@ -11,7 +11,8 @@
 #pragma once
 
 #include "root/dsystem.h"
-#include "globals.h"
+
+struct Loc;
 
 bool isConsoleColorSupported();
 
@@ -27,6 +28,7 @@ D_ATTRIBUTE_FORMAT(2, 3) void warningSupplemental(const Loc& loc, const char *fo
 D_ATTRIBUTE_FORMAT(2, 3) void deprecation(const Loc& loc, const char *format, ...);
 D_ATTRIBUTE_FORMAT(2, 3) void deprecationSupplemental(const Loc& loc, const char *format, ...);
 D_ATTRIBUTE_FORMAT(2, 3) void error(const Loc& loc, const char *format, ...);
+D_ATTRIBUTE_FORMAT(4, 5) void error(const char *filename, unsigned linnum, unsigned charnum, const char *format, ...);
 D_ATTRIBUTE_FORMAT(2, 3) void errorSupplemental(const Loc& loc, const char *format, ...);
 D_ATTRIBUTE_FORMAT(2, 0) void verror(const Loc& loc, const char *format, va_list ap, const char *p1 = NULL, const char *p2 = NULL, const char *header = "Error: ");
 D_ATTRIBUTE_FORMAT(2, 0) void verrorSupplemental(const Loc& loc, const char *format, va_list ap);
@@ -36,7 +38,9 @@ D_ATTRIBUTE_FORMAT(2, 0) void vdeprecation(const Loc& loc, const char *format, v
 D_ATTRIBUTE_FORMAT(2, 0) void vdeprecationSupplemental(const Loc& loc, const char *format, va_list ap);
 D_ATTRIBUTE_FORMAT(1, 2) void message(const char *format, ...);
 D_ATTRIBUTE_FORMAT(2, 3) void message(const Loc& loc, const char *format, ...);
-D_ATTRIBUTE_FORMAT(2, 0) void vmessage(const Loc& loc, const char *format, va_list);
+D_ATTRIBUTE_FORMAT(2, 0) void vmessage(const Loc& loc, const char *format, va_list ap);
+D_ATTRIBUTE_FORMAT(1, 2) void tip(const char *format, ...);
+D_ATTRIBUTE_FORMAT(1, 0) void vtip(const char *format, va_list ap);
 
 #if defined(__GNUC__) || defined(__clang__)
 #define D_ATTRIBUTE_NORETURN __attribute__((noreturn))
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 9413ad9a931..dec3713b676 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -13,13 +13,11 @@
 #include "ast_node.h"
 #include "complex_t.h"
 #include "globals.h"
-#include "identifier.h"
 #include "arraytypes.h"
-#include "intrange.h"
 #include "visitor.h"
 #include "tokens.h"
 
-#include "root/rmem.h"
+#include "root/dcompat.h"
 
 class Type;
 class TypeVector;
@@ -28,29 +26,17 @@ class TupleDeclaration;
 class VarDeclaration;
 class FuncDeclaration;
 class FuncLiteralDeclaration;
-class Declaration;
 class CtorDeclaration;
-class NewDeclaration;
 class Dsymbol;
-class Import;
-class Module;
 class ScopeDsymbol;
 class Expression;
 class Declaration;
-class AggregateDeclaration;
 class StructDeclaration;
 class TemplateInstance;
 class TemplateDeclaration;
 class ClassDeclaration;
-class BinExp;
-class UnaExp;
-class DotIdExp;
-class DotTemplateInstanceExp;
 class OverloadSet;
-class Initializer;
 class StringExp;
-class ArrayExp;
-class SliceExp;
 struct UnionExp;
 #ifdef IN_GCC
 typedef union tree_node Symbol;
@@ -58,113 +44,53 @@ typedef union tree_node Symbol;
 struct Symbol;          // back end symbol
 #endif
 
-Expression *expressionSemantic(Expression *e, Scope *sc);
-Expression *semanticX(DotIdExp *exp, Scope *sc);
-Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
-Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
-Expression *trySemantic(Expression *e, Scope *sc);
-Expression *unaSemantic(UnaExp *e, Scope *sc);
-Expression *binSemantic(BinExp *e, Scope *sc);
-Expression *binSemanticProp(BinExp *e, Scope *sc);
-StringExp *semanticString(Scope *sc, Expression *exp, const char *s);
-
-Expression *resolveProperties(Scope *sc, Expression *e);
-Expression *resolvePropertiesOnly(Scope *sc, Expression *e1);
-bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d);
-bool checkAccess(Scope *sc, Package *p);
-Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Dsymbol *d);
-Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid);
 void expandTuples(Expressions *exps);
-TupleDeclaration *isAliasThisTuple(Expression *e);
-int expandAliasThisTuples(Expressions *exps, size_t starti = 0);
-FuncDeclaration *hasThis(Scope *sc);
-Expression *fromConstInitializer(int result, Expression *e);
-bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors = false);
-TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);
-Expression *valueNoDtor(Expression *e);
-int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
-Expression *resolveAliasThis(Scope *sc, Expression *e, bool gag = false);
-Expression *doCopyOrMove(Scope *sc, Expression *e);
-Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0);
-Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0);
-Expression *integralPromotions(Expression *e, Scope *sc);
-bool discardValue(Expression *e);
 bool isTrivialExp(Expression *e);
-
-int isConst(Expression *e);
-Expression *toDelegate(Expression *e, Type* t, Scope *sc);
-AggregateDeclaration *isAggregate(Type *t);
-IntRange getIntRange(Expression *e);
-bool checkNonAssignmentArrayOp(Expression *e, bool suggestion = false);
-bool isUnaArrayOp(TOK op);
-bool isBinArrayOp(TOK op);
-bool isBinAssignArrayOp(TOK op);
-bool isArrayOpOperand(Expression *e);
-Expression *arrayOp(BinExp *e, Scope *sc);
-Expression *arrayOp(BinAssignExp *e, Scope *sc);
-bool hasSideEffect(Expression *e);
+bool hasSideEffect(Expression *e, bool assumeImpureCalls = false);
 bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
-Expression *Expression_optimize(Expression *e, int result, bool keepLvalue);
-MATCH implicitConvTo(Expression *e, Type *t);
-Expression *implicitCastTo(Expression *e, Scope *sc, Type *t);
-Expression *castTo(Expression *e, Scope *sc, Type *t);
-Expression *ctfeInterpret(Expression *);
-Expression *inlineCopy(Expression *e, Scope *sc);
-Expression *op_overload(Expression *e, Scope *sc);
-Type *toStaticArrayType(SliceExp *e);
-Expression *scaleFactor(BinExp *be, Scope *sc);
-Expression *typeCombine(BinExp *be, Scope *sc);
-Expression *inferType(Expression *e, Type *t, int flag = 0);
-Expression *semanticTraits(TraitsExp *e, Scope *sc);
-Type *getIndirection(Type *t);
-
-Expression *checkGC(Scope *sc, Expression *e);
-
-/* Run CTFE on the expression, but allow the expression to be a TypeExp
- * or a tuple containing a TypeExp. (This is required by pragma(msg)).
- */
-Expression *ctfeInterpretForPragmaMsg(Expression *e);
 
-enum OwnedBy
+typedef unsigned char OwnedBy;
+enum
 {
     OWNEDcode,      // normal code expression in AST
     OWNEDctfe,      // value expression for CTFE
     OWNEDcache      // constant value cached for CTFE
 };
 
-#define WANTvalue   0   // default
-#define WANTexpand  1   // expand const/immutable variables if possible
+/**
+ * Specifies how the checkModify deals with certain situations
+ */
+enum class ModifyFlags
+{
+    /// Issue error messages on invalid modifications of the variable
+    none,
+    /// No errors are emitted for invalid modifications
+    noError = 0x1,
+    /// The modification occurs for a subfield of the current variable
+    fieldAssign = 0x2,
+};
 
 class Expression : public ASTNode
 {
 public:
-    Loc loc;                    // file location
-    Type *type;                 // !=NULL means that semantic() has been run
     TOK op;                     // to minimize use of dynamic_cast
     unsigned char size;         // # of bytes in Expression so we can copy() it
     unsigned char parens;       // if this is a parenthesized expression
+    Type *type;                 // !=NULL means that semantic() has been run
+    Loc loc;                    // file location
 
-    Expression(Loc loc, TOK op, int size);
     static void _init();
     Expression *copy();
     virtual Expression *syntaxCopy();
 
     // kludge for template.isExpression()
-    int dyncast() const { return DYNCAST_EXPRESSION; }
+    DYNCAST dyncast() const { return DYNCAST_EXPRESSION; }
 
-    void print();
-    const char *toChars();
+    const char *toChars() const;
     void error(const char *format, ...) const;
     void warning(const char *format, ...) const;
     void deprecation(const char *format, ...) const;
 
-    // creates a single expression which is effectively (e1, e2)
-    // this new expression does not necessarily need to have valid D source code representation,
-    // for example, it may include declaration expressions
-    static Expression *combine(Expression *e1, Expression *e2);
-    static Expression *extractLast(Expression *e, Expression **pe0);
-    static Expressions *arraySyntaxCopy(Expressions *exps);
-
     virtual dinteger_t toInteger();
     virtual uinteger_t toUInteger();
     virtual real_t toReal();
@@ -175,58 +101,24 @@ public:
     virtual bool isLvalue();
     virtual Expression *toLvalue(Scope *sc, Expression *e);
     virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
-    Expression *implicitCastTo(Scope *sc, Type *t)
-    {
-        return ::implicitCastTo(this, sc, t);
-    }
-    MATCH implicitConvTo(Type *t)
-    {
-        return ::implicitConvTo(this, t);
-    }
-    Expression *castTo(Scope *sc, Type *t)
-    {
-        return ::castTo(this, sc, t);
-    }
-    virtual Expression *resolveLoc(Loc loc, Scope *sc);
+    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 checkScalar();
-    bool checkNoBool();
-    bool checkIntegral();
-    bool checkArithmetic();
     bool checkDeprecated(Scope *sc, Dsymbol *s);
-    bool checkDisabled(Scope *sc, Dsymbol *s);
-    bool checkPurity(Scope *sc, FuncDeclaration *f);
-    bool checkPurity(Scope *sc, VarDeclaration *v);
-    bool checkSafety(Scope *sc, FuncDeclaration *f);
-    bool checkNogc(Scope *sc, FuncDeclaration *f);
-    bool checkPostblit(Scope *sc, Type *t);
-    bool checkRightThis(Scope *sc);
-    bool checkReadModifyWrite(TOK rmwOp, Expression *ex = NULL);
-    virtual int checkModifiable(Scope *sc, int flag = 0);
-    virtual Expression *toBoolean(Scope *sc);
     virtual Expression *addDtorHook(Scope *sc);
     Expression *addressOf();
     Expression *deref();
 
-    Expression *optimize(int result, bool keepLvalue = false)
-    {
-        return Expression_optimize(this, result, keepLvalue);
-    }
+    Expression *optimize(int result, bool keepLvalue = false);
 
     // Entry point for CTFE.
     // A compile-time result is required. Give an error if not possible
-    Expression *ctfeInterpret()
-    {
-        return ::ctfeInterpret(this);
-    }
-
-    int isConst() { return ::isConst(this); }
+    Expression *ctfeInterpret();
+    int isConst();
     virtual bool isBool(bool result);
-    Expression *op_overload(Scope *sc)
-    {
-        return ::op_overload(this, sc);
-    }
 
     virtual bool hasCode()
     {
@@ -263,7 +155,7 @@ public:
     TraitsExp* isTraitsExp();
     HaltExp* isHaltExp();
     IsExp* isExp();
-    CompileExp* isCompileExp();
+    MixinExp* isMixinExp();
     ImportExp* isImportExp();
     AssertExp* isAssertExp();
     DotIdExp* isDotIdExp();
@@ -329,6 +221,7 @@ public:
     EqualExp* isEqualExp();
     IdentityExp* isIdentityExp();
     CondExp* isCondExp();
+    GenericExp* isGenericExp();
     DefaultInitExp* isDefaultInitExp();
     FileInitExp* isFileInitExp();
     LineInitExp* isLineInitExp();
@@ -336,6 +229,7 @@ public:
     FuncInitExp* isFuncInitExp();
     PrettyFuncInitExp* isPrettyFuncInitExp();
     ClassReferenceExp* isClassReferenceExp();
+    virtual BinAssignExp* isBinAssignExp();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -345,10 +239,9 @@ class IntegerExp : public Expression
 public:
     dinteger_t value;
 
-    IntegerExp(Loc loc, dinteger_t value, Type *type);
-    IntegerExp(dinteger_t value);
     static IntegerExp *create(Loc loc, dinteger_t value, Type *type);
-    bool equals(RootObject *o);
+    static void emplace(UnionExp *pue, Loc loc, dinteger_t value, Type *type);
+    bool equals(const RootObject *o) const;
     dinteger_t toInteger();
     real_t toReal();
     real_t toImaginary();
@@ -358,13 +251,13 @@ public:
     void accept(Visitor *v) { v->visit(this); }
     dinteger_t getInteger() { return value; }
     void setInteger(dinteger_t value);
-    void normalize();
+    template<int v>
+    static IntegerExp literal();
 };
 
 class ErrorExp : public Expression
 {
 public:
-    ErrorExp();
     Expression *toLvalue(Scope *sc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
 
@@ -376,9 +269,9 @@ class RealExp : public Expression
 public:
     real_t value;
 
-    RealExp(Loc loc, real_t value, Type *type);
     static RealExp *create(Loc loc, real_t value, Type *type);
-    bool equals(RootObject *o);
+    static void emplace(UnionExp *pue, Loc loc, real_t value, Type *type);
+    bool equals(const RootObject *o) const;
     dinteger_t toInteger();
     uinteger_t toUInteger();
     real_t toReal();
@@ -393,9 +286,9 @@ class ComplexExp : public Expression
 public:
     complex_t value;
 
-    ComplexExp(Loc loc, complex_t value, Type *type);
     static ComplexExp *create(Loc loc, complex_t value, Type *type);
-    bool equals(RootObject *o);
+    static void emplace(UnionExp *pue, Loc loc, complex_t value, Type *type);
+    bool equals(const RootObject *o) const;
     dinteger_t toInteger();
     uinteger_t toUInteger();
     real_t toReal();
@@ -410,7 +303,6 @@ class IdentifierExp : public Expression
 public:
     Identifier *ident;
 
-    IdentifierExp(Loc loc, Identifier *ident);
     static IdentifierExp *create(Loc loc, Identifier *ident);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
@@ -420,7 +312,6 @@ public:
 class DollarExp : public IdentifierExp
 {
 public:
-    DollarExp(Loc loc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -430,7 +321,7 @@ public:
     Dsymbol *s;
     bool hasOverloads;
 
-    DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads = true);
+    DsymbolExp *syntaxCopy();
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
@@ -441,7 +332,7 @@ class ThisExp : public Expression
 public:
     VarDeclaration *var;
 
-    ThisExp(Loc loc);
+    ThisExp *syntaxCopy();
     bool isBool(bool result);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
@@ -452,18 +343,13 @@ public:
 class SuperExp : public ThisExp
 {
 public:
-    SuperExp(Loc loc);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class NullExp : public Expression
 {
 public:
-    unsigned char committed;    // !=0 if type is committed
-
-    NullExp(Loc loc, Type *t = NULL);
-    bool equals(RootObject *o);
+    bool equals(const RootObject *o) const;
     bool isBool(bool result);
     StringExp *toStringExp();
     void accept(Visitor *v) { v->visit(this); }
@@ -479,15 +365,13 @@ public:
     utf8_t postfix;      // 'c', 'w', 'd'
     OwnedBy ownedByCtfe;
 
-    StringExp(Loc loc, char *s);
-    StringExp(Loc loc, void *s, size_t len);
-    StringExp(Loc loc, void *s, size_t len, utf8_t postfix);
     static StringExp *create(Loc loc, char *s);
     static StringExp *create(Loc loc, void *s, size_t len);
-    bool equals(RootObject *o);
+    static void emplace(UnionExp *pue, Loc loc, char *s);
+    static void emplace(UnionExp *pue, Loc loc, void *s, size_t len);
+    bool equals(const RootObject *o) const;
     StringExp *toStringExp();
     StringExp *toUTF8(Scope *sc);
-    int compare(RootObject *obj);
     bool isBool(bool result);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
@@ -496,7 +380,6 @@ public:
     void accept(Visitor *v) { v->visit(this); }
     size_t numberOfCodeUnits(int tynto = 0) const;
     void writeTo(void* dest, bool zero, int tyto = 0) const;
-    char *toPtr();
 };
 
 // Tuple
@@ -514,12 +397,10 @@ public:
      */
     Expressions *exps;
 
-    TupleExp(Loc loc, Expression *e0, Expressions *exps);
-    TupleExp(Loc loc, Expressions *exps);
-    TupleExp(Loc loc, TupleDeclaration *tup);
+    static TupleExp *create(Loc loc, Expressions *exps);
     TupleExp *toTupleExp();
-    Expression *syntaxCopy();
-    bool equals(RootObject *o);
+    TupleExp *syntaxCopy();
+    bool equals(const RootObject *o) const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -531,14 +412,12 @@ public:
     Expressions *elements;
     OwnedBy ownedByCtfe;
 
-    ArrayLiteralExp(Loc loc, Type *type, Expressions *elements);
-    ArrayLiteralExp(Loc loc, Type *type, Expression *e);
-    ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements);
     static ArrayLiteralExp *create(Loc loc, Expressions *elements);
-    Expression *syntaxCopy();
-    bool equals(RootObject *o);
-    Expression *getElement(size_t i);
-    static Expressions* copyElements(Expression *e1, Expression *e2 = NULL);
+    static void emplace(UnionExp *pue, Loc loc, Expressions *elements);
+    ArrayLiteralExp *syntaxCopy();
+    bool equals(const RootObject *o) const;
+    Expression *getElement(d_size_t i); // use opIndex instead
+    Expression *opIndex(d_size_t i);
     bool isBool(bool result);
     StringExp *toStringExp();
 
@@ -552,27 +431,13 @@ public:
     Expressions *values;
     OwnedBy ownedByCtfe;
 
-    AssocArrayLiteralExp(Loc loc, Expressions *keys, Expressions *values);
-    bool equals(RootObject *o);
-    Expression *syntaxCopy();
+    bool equals(const RootObject *o) const;
+    AssocArrayLiteralExp *syntaxCopy();
     bool isBool(bool result);
 
     void accept(Visitor *v) { v->visit(this); }
 };
 
-// scrubReturnValue is running
-#define stageScrub          0x1
-// hasNonConstPointers is running
-#define stageSearchPointers 0x2
-// optimize is running
-#define stageOptimize       0x4
-// apply is running
-#define stageApply          0x8
-//inlineScan is running
-#define stageInlineScan     0x10
-// toCBuffer is running
-#define stageToCBuffer      0x20
-
 class StructLiteralExp : public Expression
 {
 public:
@@ -580,45 +445,44 @@ public:
     Expressions *elements;      // parallels sd->fields[] with NULL entries for fields to skip
     Type *stype;                // final type of result (can be different from sd's type)
 
-    bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol
     Symbol *sym;                // back end symbol to initialize with literal
 
-    OwnedBy ownedByCtfe;
-
-    // pointer to the origin instance of the expression.
-    // once a new expression is created, origin is set to 'this'.
-    // anytime when an expression copy is created, 'origin' pointer is set to
-    // 'origin' pointer value of the original expression.
+    /** pointer to the origin instance of the expression.
+     * once a new expression is created, origin is set to 'this'.
+     * anytime when an expression copy is created, 'origin' pointer is set to
+     * 'origin' pointer value of the original expression.
+     */
     StructLiteralExp *origin;
 
     // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
     StructLiteralExp *inlinecopy;
 
-    // anytime when recursive function is calling, 'stageflags' marks with bit flag of
-    // current stage and unmarks before return from this function.
-    // 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
-    // (with infinite recursion) of this expression.
+    /** anytime when recursive function is calling, 'stageflags' marks with bit flag of
+     * current stage and unmarks before return from this function.
+     * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
+     * (with infinite recursion) of this expression.
+     */
     int stageflags;
 
-    StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype = NULL);
+    bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol
+    bool isOriginal;            // used when moving instances to indicate `this is this.origin`
+    OwnedBy ownedByCtfe;
+
     static StructLiteralExp *create(Loc loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
-    bool equals(RootObject *o);
-    Expression *syntaxCopy();
+    bool equals(const RootObject *o) const;
+    StructLiteralExp *syntaxCopy();
     Expression *getField(Type *type, unsigned offset);
     int getFieldIndex(Type *type, unsigned offset);
     Expression *addDtorHook(Scope *sc);
+    Expression *toLvalue(Scope *sc, Expression *e);
 
     void accept(Visitor *v) { v->visit(this); }
 };
 
-class DotIdExp;
-DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident);
-
 class TypeExp : public Expression
 {
 public:
-    TypeExp(Loc loc, Type *type);
-    Expression *syntaxCopy();
+    TypeExp *syntaxCopy();
     bool checkType();
     bool checkValue();
     void accept(Visitor *v) { v->visit(this); }
@@ -629,8 +493,7 @@ class ScopeExp : public Expression
 public:
     ScopeDsymbol *sds;
 
-    ScopeExp(Loc loc, ScopeDsymbol *sds);
-    Expression *syntaxCopy();
+    ScopeExp *syntaxCopy();
     bool checkType();
     bool checkValue();
     void accept(Visitor *v) { v->visit(this); }
@@ -642,7 +505,6 @@ public:
     TemplateDeclaration *td;
     FuncDeclaration *fd;
 
-    TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd = NULL);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     bool checkType();
@@ -663,13 +525,11 @@ public:
     Expression *argprefix;      // expression to be evaluated just before arguments[]
 
     CtorDeclaration *member;    // constructor function
-    NewDeclaration *allocator;  // allocator function
-    int onstack;                // allocate on stack
+    bool onstack;               // allocate on stack
+    bool thrownew;              // this NewExp is the expression of a ThrowStatement
 
-    NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
-        Type *newtype, Expressions *arguments);
     static NewExp *create(Loc loc, Expression *thisexp, Expressions *newargs, Type *newtype, Expressions *arguments);
-    Expression *syntaxCopy();
+    NewExp *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -684,9 +544,7 @@ public:
     ClassDeclaration *cd;       // class being instantiated
     Expressions *arguments;     // Array of Expression's to call class constructor
 
-    NewAnonClassExp(Loc loc, Expression *thisexp, Expressions *newargs,
-        ClassDeclaration *cd, Expressions *arguments);
-    Expression *syntaxCopy();
+    NewAnonClassExp *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -694,8 +552,8 @@ class SymbolExp : public Expression
 {
 public:
     Declaration *var;
+    Dsymbol *originalScope;
     bool hasOverloads;
-    SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads);
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -707,7 +565,6 @@ class SymOffExp : public SymbolExp
 public:
     dinteger_t offset;
 
-    SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads = true);
     bool isBool(bool result);
 
     void accept(Visitor *v) { v->visit(this); }
@@ -718,11 +575,9 @@ public:
 class VarExp : public SymbolExp
 {
 public:
-    VarExp(Loc loc, Declaration *var, bool hasOverloads = true);
+    bool delegateWasExtracted;
     static VarExp *create(Loc loc, Declaration *var, bool hasOverloads = true);
-    bool equals(RootObject *o);
-    int checkModifiable(Scope *sc, int flag);
-    bool checkReadModifyWrite();
+    bool equals(const RootObject *o) const;
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
@@ -737,7 +592,6 @@ class OverExp : public Expression
 public:
     OverloadSet *vars;
 
-    OverExp(Loc loc, OverloadSet *s);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
@@ -752,12 +606,9 @@ public:
     TemplateDeclaration *td;
     TOK tok;
 
-    FuncExp(Loc loc, Dsymbol *s);
-    bool equals(RootObject *o);
-    void genIdent(Scope *sc);
-    Expression *syntaxCopy();
-    MATCH matchType(Type *to, Scope *sc, FuncExp **pfe, int flag = 0);
-    const char *toChars();
+    bool equals(const RootObject *o) const;
+    FuncExp *syntaxCopy();
+    const char *toChars() const;
     bool checkType();
     bool checkValue();
 
@@ -774,8 +625,7 @@ class DeclarationExp : public Expression
 public:
     Dsymbol *declaration;
 
-    DeclarationExp(Loc loc, Dsymbol *declaration);
-    Expression *syntaxCopy();
+    DeclarationExp *syntaxCopy();
 
     bool hasCode();
 
@@ -787,8 +637,7 @@ class TypeidExp : public Expression
 public:
     RootObject *obj;
 
-    TypeidExp(Loc loc, RootObject *obj);
-    Expression *syntaxCopy();
+    TypeidExp *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -798,16 +647,13 @@ public:
     Identifier *ident;
     Objects *args;
 
-    TraitsExp(Loc loc, Identifier *ident, Objects *args);
-    Expression *syntaxCopy();
+    TraitsExp *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class HaltExp : public Expression
 {
 public:
-    HaltExp(Loc loc);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -819,14 +665,12 @@ public:
      */
     Type *targ;
     Identifier *id;     // can be NULL
-    TOK tok;       // ':' or '=='
     Type *tspec;        // can be NULL
-    TOK tok2;      // 'struct', 'union', etc.
     TemplateParameters *parameters;
+    TOK tok;       // ':' or '=='
+    TOK tok2;      // 'struct', 'union', etc.
 
-    IsExp(Loc loc, Type *targ, Identifier *id, TOK tok, Type *tspec,
-        TOK tok2, TemplateParameters *parameters);
-    Expression *syntaxCopy();
+    IsExp *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -838,17 +682,13 @@ public:
     Expression *e1;
     Type *att1; // Save alias this type to detect recursion
 
-    UnaExp(Loc loc, TOK op, int size, Expression *e1);
-    Expression *syntaxCopy();
+    UnaExp *syntaxCopy();
     Expression *incompatibleTypes();
-    Expression *resolveLoc(Loc loc, Scope *sc);
+    Expression *resolveLoc(const Loc &loc, Scope *sc);
 
     void accept(Visitor *v) { v->visit(this); }
 };
 
-typedef UnionExp (*fp_t)(Loc loc, Type *, Expression *, Expression *);
-typedef int (*fp2_t)(Loc loc, TOK, Expression *, Expression *);
-
 class BinExp : public Expression
 {
 public:
@@ -858,12 +698,8 @@ public:
     Type *att1; // Save alias this type to detect recursion
     Type *att2; // Save alias this type to detect recursion
 
-    BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2);
-    Expression *syntaxCopy();
+    BinExp *syntaxCopy();
     Expression *incompatibleTypes();
-    Expression *checkOpAssignTypes(Scope *sc);
-    bool checkIntegralBin();
-    bool checkArithmeticBin();
 
     Expression *reorderSettingAAElem(Scope *sc);
 
@@ -873,31 +709,24 @@ public:
 class BinAssignExp : public BinExp
 {
 public:
-    BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2);
-
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *ex);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
+    BinAssignExp* isBinAssignExp();
     void accept(Visitor *v) { v->visit(this); }
 };
 
 /****************************************************************/
 
-class CompileExp : public Expression
+class MixinExp : public UnaExp
 {
 public:
-    Expressions *exps;
-
-    CompileExp(Loc loc, Expressions *exps);
-    Expression *syntaxCopy();
-    bool equals(RootObject *o);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ImportExp : public UnaExp
 {
 public:
-    ImportExp(Loc loc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -906,8 +735,7 @@ class AssertExp : public UnaExp
 public:
     Expression *msg;
 
-    AssertExp(Loc loc, Expression *e, Expression *msg = NULL);
-    Expression *syntaxCopy();
+    AssertExp *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -919,7 +747,6 @@ public:
     bool noderef;       // true if the result of the expression will never be dereferenced
     bool wantsym;       // do not replace Symbol with its initializer during semantic()
 
-    DotIdExp(Loc loc, Expression *e, Identifier *ident);
     static DotIdExp *create(Loc loc, Expression *e, Identifier *ident);
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -929,7 +756,6 @@ class DotTemplateExp : public UnaExp
 public:
     TemplateDeclaration *td;
 
-    DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td);
     bool checkType();
     bool checkValue();
     void accept(Visitor *v) { v->visit(this); }
@@ -941,9 +767,6 @@ public:
     Declaration *var;
     bool hasOverloads;
 
-    DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads = true);
-    int checkModifiable(Scope *sc, int flag);
-    bool checkReadModifyWrite();
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
@@ -955,9 +778,7 @@ class DotTemplateInstanceExp : public UnaExp
 public:
     TemplateInstance *ti;
 
-    DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs);
-    DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti);
-    Expression *syntaxCopy();
+    DotTemplateInstanceExp *syntaxCopy();
     bool findTempDecl(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -967,8 +788,8 @@ class DelegateExp : public UnaExp
 public:
     FuncDeclaration *func;
     bool hasOverloads;
+    VarDeclaration *vthis2;  // container for multi-context
 
-    DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, bool hasOverloads = true);
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -978,7 +799,6 @@ class DotTypeExp : public UnaExp
 public:
     Dsymbol *sym;               // symbol that represents a type
 
-    DotTypeExp(Loc loc, Expression *e, Dsymbol *sym);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -988,16 +808,16 @@ public:
     Expressions *arguments;     // function arguments
     FuncDeclaration *f;         // symbol to call
     bool directcall;            // true if a virtual call is devirtualized
-    CallExp(Loc loc, Expression *e, Expressions *exps);
-    CallExp(Loc loc, Expression *e);
-    CallExp(Loc loc, Expression *e, Expression *earg1);
-    CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2);
+    bool inDebugStatement;      // true if this was in a debug statement
+    bool ignoreAttributes;      // don't enforce attributes (e.g. call @gc function in @nogc code)
+    VarDeclaration *vthis2;     // container for multi-context
 
     static CallExp *create(Loc loc, Expression *e, Expressions *exps);
     static CallExp *create(Loc loc, Expression *e);
     static CallExp *create(Loc loc, Expression *e, Expression *earg1);
+    static CallExp *create(Loc loc, FuncDeclaration *fd, Expression *earg1);
 
-    Expression *syntaxCopy();
+    CallExp *syntaxCopy();
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *addDtorHook(Scope *sc);
@@ -1008,18 +828,12 @@ public:
 class AddrExp : public UnaExp
 {
 public:
-    AddrExp(Loc loc, Expression *e);
-    AddrExp(Loc loc, Expression *e, Type *t);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class PtrExp : public UnaExp
 {
 public:
-    PtrExp(Loc loc, Expression *e);
-    PtrExp(Loc loc, Expression *e, Type *t);
-    int checkModifiable(Scope *sc, int flag);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
@@ -1030,31 +844,24 @@ public:
 class NegExp : public UnaExp
 {
 public:
-    NegExp(Loc loc, Expression *e);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class UAddExp : public UnaExp
 {
 public:
-    UAddExp(Loc loc, Expression *e);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ComExp : public UnaExp
 {
 public:
-    ComExp(Loc loc, Expression *e);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class NotExp : public UnaExp
 {
 public:
-    NotExp(Loc loc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1062,8 +869,6 @@ class DeleteExp : public UnaExp
 {
 public:
     bool isRAII;
-    DeleteExp(Loc loc, Expression *e, bool isRAII);
-    Expression *toBoolean(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1074,9 +879,9 @@ public:
     Type *to;                   // type to cast to
     unsigned char mod;          // MODxxxxx
 
-    CastExp(Loc loc, Expression *e, Type *t);
-    CastExp(Loc loc, Expression *e, unsigned char mod);
-    Expression *syntaxCopy();
+    CastExp *syntaxCopy();
+    bool isLvalue();
+    Expression *toLvalue(Scope *sc, Expression *e);
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -1088,16 +893,15 @@ public:
     unsigned dim;               // number of elements in the vector
     OwnedBy ownedByCtfe;
 
-    VectorExp(Loc loc, Expression *e, Type *t);
     static VectorExp *create(Loc loc, Expression *e, Type *t);
-    Expression *syntaxCopy();
+    static void emplace(UnionExp *pue, Loc loc, Expression *e, Type *t);
+    VectorExp *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class VectorArrayExp : public UnaExp
 {
 public:
-    VectorArrayExp(Loc loc, Expression *e1);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
@@ -1113,10 +917,7 @@ public:
     bool lowerIsLessThanUpper;  // true if lwr <= upr
     bool arrayop;               // an array operation, rather than a slice
 
-    SliceExp(Loc loc, Expression *e1, IntervalExp *ie);
-    SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr);
-    Expression *syntaxCopy();
-    int checkModifiable(Scope *sc, int flag);
+    SliceExp *syntaxCopy();
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
@@ -1128,8 +929,6 @@ public:
 class ArrayLengthExp : public UnaExp
 {
 public:
-    ArrayLengthExp(Loc loc, Expression *e1);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1139,15 +938,13 @@ public:
     Expression *lwr;
     Expression *upr;
 
-    IntervalExp(Loc loc, Expression *lwr, Expression *upr);
-    Expression *syntaxCopy();
+    IntervalExp *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class DelegatePtrExp : public UnaExp
 {
 public:
-    DelegatePtrExp(Loc loc, Expression *e1);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
@@ -1157,7 +954,6 @@ public:
 class DelegateFuncptrExp : public UnaExp
 {
 public:
-    DelegateFuncptrExp(Loc loc, Expression *e1);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
@@ -1173,9 +969,7 @@ public:
     size_t currentDimension;            // for opDollar
     VarDeclaration *lengthVar;
 
-    ArrayExp(Loc loc, Expression *e1, Expression *index = NULL);
-    ArrayExp(Loc loc, Expression *e1, Expressions *args);
-    Expression *syntaxCopy();
+    ArrayExp *syntaxCopy();
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
 
@@ -1187,7 +981,6 @@ public:
 class DotExp : public BinExp
 {
 public:
-    DotExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1196,13 +989,10 @@ class CommaExp : public BinExp
 public:
     bool isGenerated;
     bool allowCommaExp;
-    CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated = true);
-    int checkModifiable(Scope *sc, int flag);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
     bool isBool(bool result);
-    Expression *toBoolean(Scope *sc);
     Expression *addDtorHook(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -1214,15 +1004,11 @@ public:
     bool modifiable;
     bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1
 
-    IndexExp(Loc loc, Expression *e1, Expression *e2);
-    Expression *syntaxCopy();
-    int checkModifiable(Scope *sc, int flag);
+    IndexExp *syntaxCopy();
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
 
-    Expression *markSettingAAElem();
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1231,7 +1017,6 @@ public:
 class PostExp : public BinExp
 {
 public:
-    PostExp(TOK op, Loc loc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1240,12 +1025,12 @@ public:
 class PreExp : public UnaExp
 {
 public:
-    PreExp(TOK op, Loc loc, Expression *e);
     void accept(Visitor *v) { v->visit(this); }
 };
 
-enum MemorySet
+enum class MemorySet
 {
+    none            = 0,    // simple assignment
     blockAssign     = 1,    // setting the contents of an array
     referenceInit   = 2     // setting the reference of STCref variable
 };
@@ -1253,12 +1038,10 @@ enum MemorySet
 class AssignExp : public BinExp
 {
 public:
-    int memset;         // combination of MemorySet flags
+    MemorySet memset;
 
-    AssignExp(Loc loc, Expression *e1, Expression *e2);
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *ex);
-    Expression *toBoolean(Scope *sc);
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -1266,242 +1049,192 @@ public:
 class ConstructExp : public AssignExp
 {
 public:
-    ConstructExp(Loc loc, Expression *e1, Expression *e2);
-    ConstructExp(Loc loc, VarDeclaration *v, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class BlitExp : public AssignExp
 {
 public:
-    BlitExp(Loc loc, Expression *e1, Expression *e2);
-    BlitExp(Loc loc, VarDeclaration *v, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class AddAssignExp : public BinAssignExp
 {
 public:
-    AddAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class MinAssignExp : public BinAssignExp
 {
 public:
-    MinAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class MulAssignExp : public BinAssignExp
 {
 public:
-    MulAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class DivAssignExp : public BinAssignExp
 {
 public:
-    DivAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ModAssignExp : public BinAssignExp
 {
 public:
-    ModAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class AndAssignExp : public BinAssignExp
 {
 public:
-    AndAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class OrAssignExp : public BinAssignExp
 {
 public:
-    OrAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class XorAssignExp : public BinAssignExp
 {
 public:
-    XorAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class PowAssignExp : public BinAssignExp
 {
 public:
-    PowAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ShlAssignExp : public BinAssignExp
 {
 public:
-    ShlAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ShrAssignExp : public BinAssignExp
 {
 public:
-    ShrAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class UshrAssignExp : public BinAssignExp
 {
 public:
-    UshrAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class CatAssignExp : public BinAssignExp
 {
 public:
-    CatAssignExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class AddExp : public BinExp
 {
 public:
-    AddExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class MinExp : public BinExp
 {
 public:
-    MinExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class CatExp : public BinExp
 {
 public:
-    CatExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class MulExp : public BinExp
 {
 public:
-    MulExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class DivExp : public BinExp
 {
 public:
-    DivExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ModExp : public BinExp
 {
 public:
-    ModExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class PowExp : public BinExp
 {
 public:
-    PowExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ShlExp : public BinExp
 {
 public:
-    ShlExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ShrExp : public BinExp
 {
 public:
-    ShrExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class UshrExp : public BinExp
 {
 public:
-    UshrExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class AndExp : public BinExp
 {
 public:
-    AndExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class OrExp : public BinExp
 {
 public:
-    OrExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class XorExp : public BinExp
 {
 public:
-    XorExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class LogicalExp : public BinExp
 {
 public:
-    LogicalExp(Loc loc, TOK op, Expression *e1, Expression *e2);
-    Expression *toBoolean(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class CmpExp : public BinExp
 {
 public:
-    CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class InExp : public BinExp
 {
 public:
-    InExp(Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class RemoveExp : public BinExp
 {
 public:
-    RemoveExp(Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1510,8 +1243,6 @@ public:
 class EqualExp : public BinExp
 {
 public:
-    EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2);
-
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1520,7 +1251,6 @@ public:
 class IdentityExp : public BinExp
 {
 public:
-    IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1531,66 +1261,66 @@ class CondExp : public BinExp
 public:
     Expression *econd;
 
-    CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2);
-    Expression *syntaxCopy();
-    int checkModifiable(Scope *sc, int flag);
+    CondExp *syntaxCopy();
     bool isLvalue();
     Expression *toLvalue(Scope *sc, Expression *e);
     Expression *modifiableLvalue(Scope *sc, Expression *e);
-    Expression *toBoolean(Scope *sc);
     void hookDtors(Scope *sc);
 
     void accept(Visitor *v) { v->visit(this); }
 };
 
+class GenericExp : Expression
+{
+    Expression cntlExp;
+    Types *types;
+    Expressions *exps;
+
+    GenericExp *syntaxCopy();
+
+    void accept(Visitor *v) { v->visit(this); }
+};
+
 /****************************************************************/
 
 class DefaultInitExp : public Expression
 {
 public:
-    TOK subop;             // which of the derived classes this is
-
-    DefaultInitExp(Loc loc, TOK subop, int size);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class FileInitExp : public DefaultInitExp
 {
 public:
-    FileInitExp(Loc loc, TOK tok);
-    Expression *resolveLoc(Loc loc, Scope *sc);
+    Expression *resolveLoc(const Loc &loc, Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class LineInitExp : public DefaultInitExp
 {
 public:
-    LineInitExp(Loc loc);
-    Expression *resolveLoc(Loc loc, Scope *sc);
+    Expression *resolveLoc(const Loc &loc, Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ModuleInitExp : public DefaultInitExp
 {
 public:
-    ModuleInitExp(Loc loc);
-    Expression *resolveLoc(Loc loc, Scope *sc);
+    Expression *resolveLoc(const Loc &loc, Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class FuncInitExp : public DefaultInitExp
 {
 public:
-    FuncInitExp(Loc loc);
-    Expression *resolveLoc(Loc loc, Scope *sc);
+    Expression *resolveLoc(const Loc &loc, Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class PrettyFuncInitExp : public DefaultInitExp
 {
 public:
-    PrettyFuncInitExp(Loc loc);
-    Expression *resolveLoc(Loc loc, Scope *sc);
+    Expression *resolveLoc(const Loc &loc, Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -1652,45 +1382,10 @@ private:
 
 /****************************************************************/
 
-/* Special values used by the interpreter
- */
+class ObjcClassReferenceExp : public Expression
+{
+public:
+    ClassDeclaration* classDeclaration;
 
-Expression *expType(Type *type, Expression *e);
-
-UnionExp Neg(Type *type, Expression *e1);
-UnionExp Com(Type *type, Expression *e1);
-UnionExp Not(Type *type, Expression *e1);
-UnionExp Bool(Type *type, Expression *e1);
-UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1);
-UnionExp ArrayLength(Type *type, Expression *e1);
-UnionExp Ptr(Type *type, Expression *e1);
-
-UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Index(Type *type, Expression *e1, Expression *e2);
-UnionExp Cat(Type *type, Expression *e1, Expression *e2);
-
-UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
-UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
-
-UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr);
-
-// Const-folding functions used by CTFE
-
-void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex);
-void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex);
-void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex);
-
-int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len);
-int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len);
+    void accept(Visitor *v) { v->visit(this); }
+};
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index d9d59d685ca..6e794748bee 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -27,6 +27,13 @@ enum
     DIAGNOSTICoff     // disable diagnostic
 };
 
+typedef unsigned char MessageStyle;
+enum
+{
+    MESSAGESTYLEdigitalmars, // file(line,column): message
+    MESSAGESTYLEgnu          // file:line:column: message
+};
+
 // The state of array bounds checking
 typedef unsigned char CHECKENABLE;
 enum
@@ -42,26 +49,17 @@ enum
 {
     CHECKACTION_D,        // call D assert on failure
     CHECKACTION_C,        // call C assert on failure
-    CHECKACTION_halt      // cause program halt on failure
+    CHECKACTION_halt,     // cause program halt on failure
+    CHECKACTION_context   // call D assert with the error context on failure
 };
 
-enum CPU
+enum JsonFieldFlags
 {
-    x87,
-    mmx,
-    sse,
-    sse2,
-    sse3,
-    ssse3,
-    sse4_1,
-    sse4_2,
-    avx,                // AVX1 instruction set
-    avx2,               // AVX2 instruction set
-    avx512,             // AVX-512 instruction set
-
-    // Special values that don't survive past the command line processing
-    baseline,           // (default) the minimum capability CPU
-    native              // the machine the compiler is being run on
+    none         = 0,
+    compilerInfo = (1 << 0),
+    buildInfo    = (1 << 1),
+    modules      = (1 << 2),
+    semantics    = (1 << 3)
 };
 
 enum CppStdRevision
@@ -69,7 +67,24 @@ enum CppStdRevision
     CppStdRevisionCpp98 = 199711,
     CppStdRevisionCpp11 = 201103,
     CppStdRevisionCpp14 = 201402,
-    CppStdRevisionCpp17 = 201703
+    CppStdRevisionCpp17 = 201703,
+    CppStdRevisionCpp20 = 202002
+};
+
+/// Configuration for the C++ header generator
+enum class CxxHeaderMode
+{
+    none,   /// Don't generate headers
+    silent, /// Generate headers
+    verbose /// Generate headers and add comments for hidden declarations
+};
+
+/// Trivalent boolean to represent the state of a `revert`able change
+enum class FeatureState : signed char
+{
+    default_ = -1, /// Not specified by the user
+    disabled = 0,  /// Specified as `-revert=`
+    enabled = 1    /// Specified as `-preview=`
 };
 
 // Put command line switches in here
@@ -87,50 +102,65 @@ struct Param
     bool vcg_ast;       // write-out codegen-ast
     bool showColumns;   // print character (column) numbers in diagnostics
     bool vtls;          // identify thread local variables
-    char vgc;           // identify gc usage
+    bool vtemplates;    // collect and list statistics on template instantiations
+    bool vtemplatesListInstances; // collect and list statistics on template instantiations origins
+    bool vgc;           // identify gc usage
     bool vfield;        // identify non-mutable field variables
     bool vcomplex;      // identify complex/imaginary type usage
-    char symdebug;      // insert debug symbolic information
+    unsigned char symdebug;  // insert debug symbolic information
     bool symdebugref;   // insert debug information for all referenced types, too
-    bool alwaysframe;   // always emit standard stack frame
     bool optimize;      // run optimizer
-    bool map;           // generate linker .map file
-    bool is64bit;       // generate 64 bit code
-    bool isLP64;        // generate code for LP64
-    bool isLinux;       // generate code for linux
-    bool isOSX;         // generate code for Mac OSX
-    bool isWindows;     // generate code for Windows
-    bool isFreeBSD;     // generate code for FreeBSD
-    bool isOpenBSD;     // generate code for OpenBSD
-    bool isSolaris;     // generate code for Solaris
-    bool hasObjectiveC; // target supports Objective-C
-    bool mscoff;        // for Win32: write COFF object files instead of OMF
     Diagnostic useDeprecated;
     bool stackstomp;    // add stack stomping code
     bool useUnitTests;  // generate unittest code
     bool useInline;     // inline expand functions
-    bool useDIP25;      // implement http://wiki.dlang.org/DIP25
+    FeatureState useDIP25;      // implement http://wiki.dlang.org/DIP25
+    FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params
+    bool useDIP1021;    // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
     bool release;       // build release version
     bool preservePaths; // true means don't strip path from source file
     Diagnostic warnings;
-    bool pic;           // generate position-independent-code for shared libs
+    unsigned char pic;  // generate position-independent-code for shared libs
     bool color;         // use ANSI colors in console output
     bool cov;           // generate code coverage data
     unsigned char covPercent;   // 0..100 code coverage percentage required
+    bool ctfe_cov;      // generate coverage data for ctfe
     bool nofloat;       // code should not pull in floating point support
     bool ignoreUnsupportedPragmas;      // rather than error on them
-    bool enforcePropertySyntax;
     bool useModuleInfo; // generate runtime module information
     bool useTypeInfo;   // generate runtime type information
     bool useExceptions; // support exception handling
+    bool noSharedAccess; // read/write access to shared memory objects
+    bool previewIn;     // `in` means `scope const`, perhaps `ref`, accepts rvalues
+    bool shortenedMethods; // allow => in normal function declarations
     bool betterC;       // be a "better C" compiler; no dependency on D runtime
     bool addMain;       // add a default main() function
     bool allInst;       // generate code for all template instantiations
-    bool vsafe;         // use enhanced @safe checking
-    unsigned cplusplus;     // version of C++ name mangling to support
+    bool fix16997;      // fix integral promotions for unary + - ~ operators
+                        // https://issues.dlang.org/show_bug.cgi?id=16997
+    bool fixAliasThis;  // if the current scope has an alias this, check it before searching upper scopes
+    bool inclusiveInContracts;   // 'in' contracts of overridden methods must be a superset of parent contract
+    bool ehnogc;        // use @nogc exception handling
+    FeatureState dtorFields;  // destruct fields of partially constructed objects
+                              // https://issues.dlang.org/show_bug.cgi?id=14246
+    bool fieldwise;         // do struct equality testing field-wise rather than by memcmp()
+    bool rvalueRefParam;    // allow rvalues to be arguments to ref parameters
+    CppStdRevision cplusplus;  // version of C++ name mangling to support
+    bool markdown;          // enable Markdown replacements in Ddoc
+    bool vmarkdown;         // list instances of Markdown replacements in Ddoc
     bool showGaggedErrors;  // print gagged errors anyway
-
-    CPU cpu;                // CPU instruction set to target
+    bool printErrorContext;  // print errors with the error context (the error line in the source file)
+    bool manual;            // open browser on compiler manual
+    bool usage;             // print usage and exit
+    bool mcpuUsage;         // print help on -mcpu switch
+    bool transitionUsage;   // print help on -transition switch
+    bool checkUsage;        // print help on -check switch
+    bool checkActionUsage;  // print help on -checkaction switch
+    bool revertUsage;       // print help on -revert switch
+    bool previewUsage;      // print help on -preview switch
+    bool externStdUsage;    // print help on -extern-std switch
+    bool hcUsage;           // print help on -HC switch
+    bool logo;              // print logo;
 
     CHECKENABLE useInvariants;     // generate class invariant checks
     CHECKENABLE useIn;             // generate precondition checks
@@ -162,8 +192,17 @@ struct Param
     DString hdrname;       // write 'header' file to docname
     bool hdrStripPlainFunctions; // strip the bodies of plain (non-template) functions
 
+    CxxHeaderMode doCxxHdrGeneration;  // write 'Cxx header' file
+    DString cxxhdrdir;        // write 'header' file to docdir directory
+    DString cxxhdrname;       // write 'header' file to docname
+
     bool doJsonGeneration;    // write JSON file
     DString jsonfilename;     // write JSON file to jsonfilename
+    unsigned jsonFieldFlags;  // JSON field flags to include
+
+    OutBuffer *mixinOut;                // write expanded mixins for debugging
+    const char *mixinFile;             // .mixin file output name
+    int mixinLines;                     // Number of lines in writeMixins
 
     unsigned debuglevel;   // debug level
     Array<const char *> *debugids;     // debug identifiers
@@ -178,13 +217,11 @@ struct Param
     DString moduleDepsFile;     // filename for deps output
     OutBuffer *moduleDeps;      // contents to be written to deps file
 
-    // Hidden debug switches
-    bool debugb;
-    bool debugc;
-    bool debugf;
-    bool debugr;
-    bool debugx;
-    bool debugy;
+    bool emitMakeDeps;                // whether to emit makedeps
+    DString makeDepsFile;             // filename for makedeps output
+    Array<const char *> makeDeps;     // dependencies for makedeps
+
+    MessageStyle messageStyle;  // style of file/line annotations on messages
 
     bool run;           // run resulting executable
     Strings runargs;    // arguments for executable
@@ -192,6 +229,7 @@ struct Param
     // Linker stuff
     Array<const char *> objfiles;
     Array<const char *> linkswitches;
+    Array<bool> linkswitchIsForCC;
     Array<const char *> libfiles;
     Array<const char *> dllfiles;
     DString deffile;
@@ -205,36 +243,30 @@ typedef unsigned structalign_t;
 // other values are all powers of 2
 #define STRUCTALIGN_DEFAULT ((structalign_t) ~0)
 
+const DString mars_ext = "d";
+const DString doc_ext  = "html";     // for Ddoc generated files
+const DString ddoc_ext = "ddoc";     // for Ddoc macro include files
+const DString dd_ext   = "dd";       // for Ddoc source files
+const DString hdr_ext  = "di";       // for D 'header' import files
+const DString json_ext = "json";     // for JSON files
+const DString map_ext  = "map";      // for .map files
+
 struct Global
 {
     DString inifilename;
-    DString mars_ext;
-    DString obj_ext;
-    DString lib_ext;
-    DString dll_ext;
-    DString doc_ext;            // for Ddoc generated files
-    DString ddoc_ext;           // for Ddoc macro include files
-    DString hdr_ext;            // for D 'header' import files
-    DString cxxhdr_ext;         // for C/C++ 'header' files
-    DString json_ext;           // for JSON files
-    DString map_ext;            // for .map files
-    bool run_noext;             // allow -run sources without extensions.
-
-    DString copyright;
-    DString written;
-    const char *main_d;         // dummy filename for dummy main()
+
+    const DString copyright;
+    const DString written;
     Array<const char *> *path;        // Array of char*'s which form the import lookup path
     Array<const char *> *filePath;    // Array of char*'s which form the file import lookup path
 
-    DString version;         // Compiler version string
     DString vendor;          // Compiler backend name
 
     Param params;
-    unsigned errors;       // number of errors reported so far
-    unsigned warnings;     // number of warnings reported so far
-    FILE *stdmsg;          // where to send verbose messages
-    unsigned gag;          // !=0 means gag reporting of errors & warnings
-    unsigned gaggedErrors; // number of errors reported while gagged
+    unsigned errors;         // number of errors reported so far
+    unsigned warnings;       // number of warnings reported so far
+    unsigned gag;            // !=0 means gag reporting of errors & warnings
+    unsigned gaggedErrors;   // number of errors reported while gagged
     unsigned gaggedWarnings; // number of warnings reported while gagged
 
     void* console;         // opaque pointer to console for controlling text attributes
@@ -242,8 +274,6 @@ struct Global
     Array<class Identifier*>* versionids; // command line versions and predefined versions
     Array<class Identifier*>* debugids;   // command line debug versions and predefined versions
 
-    enum { recursionLimit = 500 }; // number of recursive template expansions before abort
-
     /* Start gagging. Return the current number of gagged errors
      */
     unsigned startGagging();
@@ -260,17 +290,43 @@ struct Global
     void increaseErrorCount();
 
     void _init();
+
+    /**
+    Returns: the version as the number that would be returned for __VERSION__
+    */
+    unsigned versionNumber();
+
+    /**
+    Returns: the compiler version string.
+    */
+    const char * versionChars();
 };
 
 extern Global global;
 
+// Because int64_t and friends may be any integral type of the correct size,
+// we have to explicitly ask for the correct integer type to get the correct
+// mangling with dmd. The #if logic here should match the mangling of
+// Tint64 and Tuns64 in cppmangle.d.
+#if MARS && DMD_VERSION >= 2079 && DMD_VERSION <= 2081 && \
+    __APPLE__ && __SIZEOF_LONG__ == 8
+// DMD versions between 2.079 and 2.081 mapped D long to int64_t on OS X.
+typedef uint64_t dinteger_t;
+typedef int64_t sinteger_t;
+typedef uint64_t uinteger_t;
+#elif __SIZEOF_LONG__ == 8
 // Be careful not to care about sign when using dinteger_t
 // use this instead of integer_t to
 // avoid conflicts with system #include's
-typedef uint64_t dinteger_t;
+typedef unsigned long dinteger_t;
 // Signed and unsigned variants
-typedef int64_t sinteger_t;
-typedef uint64_t uinteger_t;
+typedef long sinteger_t;
+typedef unsigned long uinteger_t;
+#else
+typedef unsigned long long dinteger_t;
+typedef long long sinteger_t;
+typedef unsigned long long uinteger_t;
+#endif
 
 typedef int8_t                  d_int8;
 typedef uint8_t                 d_uns8;
@@ -295,43 +351,50 @@ struct Loc
         filename = NULL;
     }
 
-    Loc(const char *filename, unsigned linnum, unsigned charnum);
+    Loc(const char *filename, unsigned linnum, unsigned charnum)
+    {
+        this->linnum = linnum;
+        this->charnum = charnum;
+        this->filename = filename;
+    }
 
-    const char *toChars() const;
-    bool equals(const Loc& loc);
+    const char *toChars(
+        bool showColumns = global.params.showColumns,
+        MessageStyle messageStyle = global.params.messageStyle) const;
+    bool equals(const Loc& loc) const;
 };
 
-enum LINK
+enum class LINK : uint8_t
 {
-    LINKdefault,
-    LINKd,
-    LINKc,
-    LINKcpp,
-    LINKwindows,
-    LINKobjc,
-    LINKsystem
+    default_,
+    d,
+    c,
+    cpp,
+    windows,
+    objc,
+    system
 };
 
-enum CPPMANGLE
+enum class CPPMANGLE : uint8_t
 {
-    CPPMANGLEdefault,
-    CPPMANGLEstruct,
-    CPPMANGLEclass
+    def,
+    asStruct,
+    asClass
 };
 
-enum MATCH
+enum class MATCH : int
 {
-    MATCHnomatch,       // no match
-    MATCHconvert,       // match with conversions
-    MATCHconst,         // match with conversion to const
-    MATCHexact          // exact match
+    nomatch,       // no match
+    convert,       // match with conversions
+    constant,      // match with conversion to const
+    exact          // exact match
 };
 
-enum PINLINE
+enum class PINLINE : uint8_t
 {
-    PINLINEdefault,      // as specified on the command line
-    PINLINEnever,        // never inline
-    PINLINEalways        // always inline
+    default_,     // as specified on the command line
+    never,        // never inline
+    always        // always inline
 };
 
 typedef uinteger_t StorageClass;
diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h
index 6822aaf44a9..531d5d8c0da 100644
--- a/gcc/d/dmd/hdrgen.h
+++ b/gcc/d/dmd/hdrgen.h
@@ -10,45 +10,12 @@
 
 #pragma once
 
-#include "root/dsystem.h"               // memset()
-#include "dsymbol.h"
+#include "globals.h"
+#include "mtype.h"
 
-void genhdrfile(Module *m);
-
-struct HdrGenState
-{
-    bool hdrgen;        // true if generating header file
-    bool ddoc;          // true if generating Ddoc file
-    bool fullDump;      // true if generating a full AST dump file
-    bool fullQual;      // fully qualify types when printing
-    int tpltMember;
-    int autoMember;
-    int forStmtInit;
-
-    HdrGenState() { memset(this, 0, sizeof(HdrGenState)); }
-};
-
-void toCBuffer(Statement *s, OutBuffer *buf, HdrGenState *hgs);
-void toCBuffer(Type *t, OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
-void toCBuffer(Dsymbol *s, OutBuffer *buf, HdrGenState *hgs);
-void toCBuffer(Initializer *iz, OutBuffer *buf, HdrGenState *hgs);
-void toCBuffer(Expression *e, OutBuffer *buf, HdrGenState *hgs);
-void toCBuffer(TemplateParameter *tp, OutBuffer *buf, HdrGenState *hgs);
-
-void toCBufferInstance(TemplateInstance *ti, OutBuffer *buf, bool qualifyTypes = false);
-
-void functionToBufferFull(TypeFunction *tf, OutBuffer *buf, Identifier *ident, HdrGenState* hgs, TemplateDeclaration *td);
-void functionToBufferWithIdent(TypeFunction *t, OutBuffer *buf, const char *ident);
-
-void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments);
-
-void arrayObjectsToBuffer(OutBuffer *buf, Objects *objects);
+class Module;
 
+void genhdrfile(Module *m);
+void genCppHdrFiles(Modules &ms);
 void moduleToBuffer(OutBuffer *buf, Module *m);
-
 const char *parametersTypeToChars(ParameterList pl);
-const char *parameterToChars(Parameter *parameter, TypeFunction *tf, bool fullQual);
-
-bool stcToBuffer(OutBuffer *buf, StorageClass stc);
-const char *stcToChars(StorageClass& stc);
-const char *linkageToChars(LINK linkage);
diff --git a/gcc/d/dmd/id.h b/gcc/d/dmd/id.h
new file mode 100644
index 00000000000..8066747c69b
--- /dev/null
+++ b/gcc/d/dmd/id.h
@@ -0,0 +1,16 @@
+
+/* Compiler implementation of the D programming language
+ * Copyright (C) 2017-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
+ * http://www.digitalmars.com
+ * Distributed under the Boost Software License, Version 1.0.
+ * http://www.boost.org/LICENSE_1_0.txt
+ * https://github.com/dlang/dmd/blob/master/src/dmd/id.h
+ */
+
+#pragma once
+
+struct Id
+{
+    static void initialize();
+};
diff --git a/gcc/d/dmd/identifier.h b/gcc/d/dmd/identifier.h
index 278ce9b8a76..790d5a036d4 100644
--- a/gcc/d/dmd/identifier.h
+++ b/gcc/d/dmd/identifier.h
@@ -10,40 +10,32 @@
 
 #pragma once
 
-#include "root/root.h"
-#include "root/stringtable.h"
+#include "root/dcompat.h"
+#include "root/object.h"
 
 class Identifier : public RootObject
 {
 private:
     int value;
-    const char *string;
-    size_t len;
+    bool isAnonymous_;
+    DString string;
 
 public:
-    Identifier(const char *string, size_t length, int value);
-    Identifier(const char *string);
     static Identifier* create(const char *string);
-    bool equals(RootObject *o);
-    int compare(RootObject *o);
-    void print();
-    const char *toChars();
+    bool equals(const RootObject *o) const;
+    const char *toChars() const;
     int getValue() const;
-    const char *toHChars2();
-    int dyncast() const;
+    bool isAnonymous() const;
+    const char *toHChars2() const;
+    DYNCAST dyncast() const;
 
-    static StringTable stringtable;
-    static Identifier *generateId(const char *prefix);
-    static Identifier *generateId(const char *prefix, size_t i);
-    static Identifier *idPool(const char *s, size_t len);
-    static Identifier *idPool(const char *s, size_t len, int value);
+    static Identifier *generateId(const char *prefix, size_t length, size_t suffix);
+    static Identifier *idPool(const char *s, unsigned len);
 
     static inline Identifier *idPool(const char *s)
     {
-        return idPool(s, strlen(s));
+        return idPool(s, static_cast<unsigned>(strlen(s)));
     }
 
     static bool isValidIdentifier(const char *p);
-    static Identifier *lookup(const char *s, size_t len);
-    static void initTable();
 };
diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h
index 07fb32aa070..34c5a05a8cd 100644
--- a/gcc/d/dmd/import.h
+++ b/gcc/d/dmd/import.h
@@ -16,7 +16,6 @@ class Identifier;
 struct Scope;
 class Module;
 class Package;
-class AliasDeclaration;
 
 class Import : public Dsymbol
 {
@@ -24,11 +23,11 @@ public:
     /* static import aliasId = pkg1.pkg2.id : alias1 = name1, alias2 = name2;
      */
 
-    Identifiers *packages;      // array of Identifier's representing packages
+    DArray<Identifier*> packages;      // array of Identifier's representing packages
     Identifier *id;             // module Identifier
     Identifier *aliasId;
     int isstatic;               // !=0 if static import
-    Prot protection;
+    Visibility visibility;
 
     // Pairs of alias=name to bind into current namespace
     Identifiers names;
@@ -39,15 +38,11 @@ public:
 
     AliasDeclarations aliasdecls; // corresponding AliasDeclarations for alias=name pairs
 
-    Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *aliasId,
-        int isstatic);
-    void addAlias(Identifier *name, Identifier *alias);
     const char *kind() const;
-    Prot prot();
-    Dsymbol *syntaxCopy(Dsymbol *s);    // copy only syntax trees
+    Visibility visible();
+    Import *syntaxCopy(Dsymbol *s);    // copy only syntax trees
     void load(Scope *sc);
     void importAll(Scope *sc);
-    void addPackageAccess(ScopeDsymbol *scopesym);
     Dsymbol *toAlias();
     void addMember(Scope *sc, ScopeDsymbol *sds);
     void setScope(Scope* sc);
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 4ba18d6a474..23204b81253 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -10,7 +10,6 @@
 
 #pragma once
 
-#include "root/root.h"
 #include "ast_node.h"
 #include "globals.h"
 #include "arraytypes.h"
@@ -18,36 +17,31 @@
 
 class Identifier;
 class Expression;
-struct Scope;
 class Type;
-class AggregateDeclaration;
-class Initializer;
 class ErrorInitializer;
 class VoidInitializer;
 class StructInitializer;
 class ArrayInitializer;
 class ExpInitializer;
+class CInitializer;
 
 enum NeedInterpret { INITnointerpret, INITinterpret };
 
-Initializer *initializerSemantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
-
 class Initializer : public ASTNode
 {
 public:
     Loc loc;
+    unsigned char kind;
 
-    Initializer(Loc loc);
-    virtual Initializer *syntaxCopy() = 0;
-    static Initializers *arraySyntaxCopy(Initializers *ai);
+    const char *toChars() const;
 
-    const char *toChars();
+    ErrorInitializer   *isErrorInitializer();
+    VoidInitializer    *isVoidInitializer();
+    StructInitializer  *isStructInitializer();
+    ArrayInitializer   *isArrayInitializer();
+    ExpInitializer     *isExpInitializer();
+    CInitializer       *isCInitializer();
 
-    virtual ErrorInitializer   *isErrorInitializer() { return NULL; }
-    virtual VoidInitializer    *isVoidInitializer() { return NULL; }
-    virtual StructInitializer  *isStructInitializer()  { return NULL; }
-    virtual ArrayInitializer   *isArrayInitializer()  { return NULL; }
-    virtual ExpInitializer     *isExpInitializer()  { return NULL; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -56,20 +50,12 @@ class VoidInitializer : public Initializer
 public:
     Type *type;         // type that this will initialize to
 
-    VoidInitializer(Loc loc);
-    Initializer *syntaxCopy();
-
-    virtual VoidInitializer *isVoidInitializer() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ErrorInitializer : public Initializer
 {
 public:
-    ErrorInitializer();
-    Initializer *syntaxCopy();
-
-    virtual ErrorInitializer *isErrorInitializer() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -79,11 +65,6 @@ public:
     Identifiers field;  // of Identifier *'s
     Initializers value; // parallel array of Initializer *'s
 
-    StructInitializer(Loc loc);
-    Initializer *syntaxCopy();
-    void addInit(Identifier *field, Initializer *value);
-
-    StructInitializer *isStructInitializer() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -96,26 +77,40 @@ public:
     Type *type;         // type that array will be used to initialize
     bool sem;           // true if semantic() is run
 
-    ArrayInitializer(Loc loc);
-    Initializer *syntaxCopy();
-    void addInit(Expression *index, Initializer *value);
-    bool isAssociativeArray();
+    bool isAssociativeArray() const;
     Expression *toAssocArrayLiteral();
 
-    ArrayInitializer *isArrayInitializer() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class ExpInitializer : public Initializer
 {
 public:
-    Expression *exp;
     bool expandTuples;
+    Expression *exp;
+
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+struct Designator
+{
+    Expression *exp;
+    Identifier *ident;
+};
+
+struct DesigInit
+{
+    Designators *designatorList;
+    Initializer *initializer;
+};
 
-    ExpInitializer(Loc loc, Expression *exp);
-    Initializer *syntaxCopy();
+class CInitializer : public Initializer
+{
+public:
+    DesigInits initializerList;
+    Type *type;         // type that array will be used to initialize
+    bool sem;           // true if semantic() is run
 
-    ExpInitializer *isExpInitializer() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
diff --git a/gcc/d/dmd/json.h b/gcc/d/dmd/json.h
index d680001000f..1311fb3ab2e 100644
--- a/gcc/d/dmd/json.h
+++ b/gcc/d/dmd/json.h
@@ -11,7 +11,9 @@
 #pragma once
 
 #include "arraytypes.h"
+#include "globals.h"
 
 struct OutBuffer;
 
 void json_generate(OutBuffer *, Modules *);
+JsonFieldFlags tryParseJsonField(const char *fieldName);
diff --git a/gcc/d/dmd/mangle.h b/gcc/d/dmd/mangle.h
index 544f77b8b0b..670cf4d6230 100644
--- a/gcc/d/dmd/mangle.h
+++ b/gcc/d/dmd/mangle.h
@@ -17,16 +17,16 @@ class TemplateInstance;
 class Type;
 struct OutBuffer;
 
-// In cppmangle.c
+// In cppmangle.d
 const char *toCppMangleItanium(Dsymbol *s);
 const char *cppTypeInfoMangleItanium(Dsymbol *s);
 const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset);
 
-// In cppmanglewin.c
+// In cppmanglewin.d
 const char *toCppMangleMSVC(Dsymbol *s);
 const char *cppTypeInfoMangleMSVC(Dsymbol *s);
 
-// In dmangle.c
+// In dmangle.d
 const char *mangleExact(FuncDeclaration *fd);
 void mangleToBuffer(Type *s, OutBuffer *buf);
 void mangleToBuffer(Expression *s, OutBuffer *buf);
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 1664492bc2d..969290c476c 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -10,15 +10,16 @@
 
 #pragma once
 
-#include "root/root.h"
 #include "dsymbol.h"
 
-class ClassDeclaration;
 struct ModuleDeclaration;
-struct Macro;
 struct Escape;
-class VarDeclaration;
-class Library;
+struct FileBuffer;
+
+struct MacroTable
+{
+    void* internal;  // PIMPL
+};
 
 enum PKG
 {
@@ -34,10 +35,9 @@ public:
     unsigned tag;       // auto incremented tag, used to mask package tree in scopes
     Module *mod;        // != NULL if isPkgMod == PKGmodule
 
-    Package(Identifier *ident);
     const char *kind() const;
 
-    static DsymbolTable *resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg);
+    bool equals(const RootObject *o) const;
 
     Package *isPackage() { return this; }
 
@@ -47,7 +47,6 @@ public:
     void accept(Visitor *v) { v->visit(this); }
 
     Module *isPackageMod();
-    void resolvePKGunknown();
 };
 
 class Module : public Package
@@ -60,26 +59,31 @@ public:
     static Dsymbols deferred2;  // deferred Dsymbol's needing semantic2() run on them
     static Dsymbols deferred3;  // deferred Dsymbol's needing semantic3() run on them
     static unsigned dprogress;  // progress resolving the deferred list
+
     static void _init();
 
     static AggregateDeclaration *moduleinfo;
 
 
-    const char *arg;    // original argument name
+    DString arg;        // original argument name
     ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
-    File *srcfile;      // input source file
-    File *objfile;      // output .obj file
-    File *hdrfile;      // 'header' file
-    File *docfile;      // output documentation file
+    FileName srcfile;   // input source file
+    FileName objfile;   // output .obj file
+    FileName hdrfile;   // 'header' file
+    FileName docfile;   // output documentation file
+    FileBuffer *srcBuffer; // set during load(), free'd in parse()
     unsigned errors;    // if any errors in file
     unsigned numlines;  // number of lines in source file
-    int isDocFile;      // if it is a documentation input file, not D source
+    bool isHdrFile;     // if it is a header (.di) file
+    bool isCFile;       // if it is a C (.c) file
+    bool isDocFile;     // if it is a documentation input file, not D source
+    bool hasAlwaysInlines; // contains references to functions that must be inlined
     bool isPackageFile; // if it is a package.d
     Package *pkg;       // if isPackageFile is true, the Package that contains this package.d
     Strings contentImportedFiles;  // array of files whose content was imported
     int needmoduleinfo;
-
     int selfimports;            // 0: don't know, 1: does not, 2: does
+    void* tagSymTab;            // ImportC: tag symbols that conflict with other symbols used as the index
     bool selfImports();         // returns true if module imports itself
 
     int rootimports;            // 0: don't know, 1: does not, 2: does
@@ -101,41 +105,34 @@ public:
 
     unsigned debuglevel;        // debug level
     Identifiers *debugids;      // debug identifiers
-    Identifiers *debugidsNot;       // forward referenced debug identifiers
+    Identifiers *debugidsNot;   // forward referenced debug identifiers
 
     unsigned versionlevel;      // version level
     Identifiers *versionids;    // version identifiers
-    Identifiers *versionidsNot;     // forward referenced version identifiers
+    Identifiers *versionidsNot; // forward referenced version identifiers
 
-    Macro *macrotable;          // document comment macros
+    MacroTable macrotable;      // document comment macros
     Escape *escapetable;        // document comment escapes
 
     size_t nameoffset;          // offset of module name from start of ModuleInfo
     size_t namelen;             // length of module name in characters
 
-    Module(const char *arg, Identifier *ident, int doDocComment, int doHdrGen);
     static Module* create(const char *arg, Identifier *ident, int doDocComment, int doHdrGen);
 
     static Module *load(Loc loc, Identifiers *packages, Identifier *ident);
 
     const char *kind() const;
-    File *setOutfile(const char *name, const char *dir, const char *arg, const char *ext);
-    void setDocfile();
-    bool read(Loc loc); // read file, returns 'true' if succeed, 'false' otherwise.
+    bool read(const Loc &loc); // read file, returns 'true' if succeed, 'false' otherwise.
     Module *parse();    // syntactic parse
     void importAll(Scope *sc);
     int needModuleInfo();
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
-    bool isPackageAccessible(Package *p, Prot protection, int flags = 0);
+    bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0);
     Dsymbol *symtabInsert(Dsymbol *s);
     void deleteObjFile();
-    static void addDeferredSemantic(Dsymbol *s);
-    static void addDeferredSemantic2(Dsymbol *s);
-    static void addDeferredSemantic3(Dsymbol *s);
     static void runDeferredSemantic();
     static void runDeferredSemantic2();
     static void runDeferredSemantic3();
-    static void clearCache();
     int imports(Module *m);
 
     bool isRoot() { return this->importedFrom == this; }
@@ -158,6 +155,8 @@ public:
 
     Symbol *sfilename;          // symbol for filename
 
+    void *ctfe_cov;             // stores coverage information from ctfe
+
     Module *isModule() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -167,11 +166,9 @@ struct ModuleDeclaration
 {
     Loc loc;
     Identifier *id;
-    Identifiers *packages;            // array of Identifier's representing packages
+    DArray<Identifier*> packages;  // array of Identifier's representing packages
     bool isdeprecated;  // if it is a deprecated module
     Expression *msg;
 
-    ModuleDeclaration(Loc loc, Identifiers *packages, Identifier *id);
-
-    const char *toChars();
+    const char *toChars() const;
 };
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 3687053488d..cdf221f55f7 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -10,15 +10,15 @@
 
 #pragma once
 
-#include "root/root.h"
-#include "root/stringtable.h"
+#include "root/dcompat.h" // for d_size_t
 
 #include "arraytypes.h"
 #include "ast_node.h"
-#include "expression.h"
+#include "globals.h"
 #include "visitor.h"
 
 struct Scope;
+class AggregateDeclaration;
 class Identifier;
 class Expression;
 class StructDeclaration;
@@ -28,7 +28,6 @@ class TypeInfoDeclaration;
 class Dsymbol;
 class TemplateInstance;
 class TemplateDeclaration;
-enum LINK;
 
 class TypeBasic;
 class Parameter;
@@ -40,12 +39,12 @@ typedef union tree_node type;
 typedef struct TYPE type;
 #endif
 
-Type *typeSemantic(Type *type, const Loc &loc, Scope *sc);
 void semanticTypeInfo(Scope *sc, Type *t);
-MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm = NULL, size_t inferStart = 0);
-StorageClass ModToStc(unsigned mod);
 
-enum ENUMTY
+Type *typeSemantic(Type *t, const Loc &loc, Scope *sc);
+Type *merge(Type *type);
+
+enum class TY : uint8_t
 {
     Tarray,             // slice array, aka T[]
     Tsarray,            // static array, aka T[dimension]
@@ -100,7 +99,6 @@ enum ENUMTY
     Tnoreturn,
     TMAX
 };
-typedef unsigned char TY;       // ENUMTY
 
 #define SIZE_INVALID (~(d_uns64)0)   // error return from size() functions
 
@@ -120,22 +118,22 @@ enum MODFlags
 };
 typedef unsigned char MOD;
 
-// These tables are for implicit conversion of binary ops;
-// the indices are the type of operand one, followed by operand two.
-extern unsigned char impcnvResult[TMAX][TMAX];
-extern unsigned char impcnvType1[TMAX][TMAX];
-extern unsigned char impcnvType2[TMAX][TMAX];
-
-// If !=0, give warning on implicit conversion
-extern unsigned char impcnvWarn[TMAX][TMAX];
+enum class Covariant
+{
+    distinct = 0,
+    yes = 1,
+    no = 2,
+    fwdref = 3,
+};
 
-enum VarArg
+enum VarArgValues
 {
     VARARGnone     = 0,  /// fixed number of arguments
     VARARGvariadic = 1,  /// T t, ...)  can be C-style (core.stdc.stdarg) or D-style (core.vararg)
     VARARGtypesafe = 2   /// T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions
                          ///   or https://dlang.org/spec/function.html#typesafe_variadic_functions
 };
+typedef unsigned char VarArg;
 
 class Type : public ASTNode
 {
@@ -144,22 +142,10 @@ public:
     MOD mod;  // modifiers MODxxxx
     char *deco;
 
-    /* These are cached values that are lazily evaluated by constOf(), immutableOf(), etc.
-     * They should not be referenced by anybody but mtype.c.
-     * They can be NULL if not lazily evaluated yet.
-     * Note that there is no "shared immutable", because that is just immutable
-     * Naked == no MOD bits
-     */
-
-    Type *cto;          // MODconst                 ? naked version of this type : const version
-    Type *ito;          // MODimmutable             ? naked version of this type : immutable version
-    Type *sto;          // MODshared                ? naked version of this type : shared mutable version
-    Type *scto;         // MODshared | MODconst     ? naked version of this type : shared const version
-    Type *wto;          // MODwild                  ? naked version of this type : wild version
-    Type *wcto;         // MODwildconst             ? naked version of this type : wild const version
-    Type *swto;         // MODshared | MODwild      ? naked version of this type : shared wild version
-    Type *swcto;        // MODshared | MODwildconst ? naked version of this type : shared wild const version
+private:
+    void* mcache;
 
+public:
     Type *pto;          // merged pointer to this type
     Type *rto;          // reference to this type
     Type *arrayof;      // array of this type
@@ -229,35 +215,27 @@ public:
 
     static TemplateDeclaration *rtinfo;
 
-    static Type *basic[TMAX];
-    static unsigned char sizeTy[TMAX];
-    static StringTable stringtable;
+    static Type *basic[(int)TY::TMAX];
 
-    Type(TY ty);
     virtual const char *kind();
-    Type *copy();
+    Type *copy() const;
     virtual Type *syntaxCopy();
-    bool equals(RootObject *o);
+    bool equals(const RootObject *o) const;
     bool equivalent(Type *t);
     // kludge for template.isType()
-    int dyncast() const { return DYNCAST_TYPE; }
-    int covariant(Type *t, StorageClass *pstc = NULL, bool fix17349 = true);
-    const char *toChars();
+    DYNCAST dyncast() const { return DYNCAST_TYPE; }
+    Covariant covariant(Type *t, StorageClass *pstc = NULL);
+    const char *toChars() const;
     char *toPrettyChars(bool QualifyTypes = false);
     static void _init();
 
     d_uns64 size();
-    virtual d_uns64 size(Loc loc);
+    virtual d_uns64 size(const Loc &loc);
     virtual unsigned alignsize();
-    Type *trySemantic(Loc loc, Scope *sc);
-    Type *merge();
+    Type *trySemantic(const Loc &loc, Scope *sc);
     Type *merge2();
-    void modToBuffer(OutBuffer *buf);
-    char *modToChars();
-
-    /** For each active modifier (MODconst, MODimmutable, etc) call fp with a
-    void* for the work param and a string representation of the attribute. */
-    int modifiersApply(void *param, int (*fp)(void *, const char *));
+    void modToBuffer(OutBuffer *buf) const;
+    char *modToChars() const;
 
     virtual bool isintegral();
     virtual bool isfloating();   // real, imaginary, or complex
@@ -270,7 +248,7 @@ public:
     virtual bool isString();
     virtual bool isAssignable();
     virtual bool isBoolean();
-    virtual void checkDeprecated(Loc loc, Scope *sc);
+    virtual void checkDeprecated(const Loc &loc, Scope *sc);
     bool isConst() const       { return (mod & MODconst) != 0; }
     bool isImmutable() const   { return (mod & MODimmutable) != 0; }
     bool isMutable() const     { return (mod & (MODconst | MODimmutable | MODwild)) == 0; }
@@ -280,7 +258,7 @@ public:
     bool isWildConst() const   { return (mod & MODwildconst) == MODwildconst; }
     bool isSharedWild() const  { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); }
     bool isNaked() const       { return mod == 0; }
-    Type *nullAttributes();
+    Type *nullAttributes() const;
     Type *constOf();
     Type *immutableOf();
     Type *mutableOf();
@@ -301,8 +279,8 @@ public:
     Type *referenceTo();
     Type *arrayOf();
     Type *sarrayOf(dinteger_t dim);
+    bool hasDeprecatedAliasThis();
     Type *aliasthisOf();
-    bool checkAliasThisRec();
     virtual Type *makeConst();
     virtual Type *makeImmutable();
     virtual Type *makeShared();
@@ -313,7 +291,7 @@ public:
     virtual Type *makeSharedWildConst();
     virtual Type *makeMutable();
     virtual Dsymbol *toDsymbol(Scope *sc);
-    virtual Type *toBasetype();
+    Type *toBasetype();
     virtual bool isBaseOf(Type *t, int *poffset);
     virtual MATCH implicitConvTo(Type *to);
     virtual MATCH constConv(Type *to);
@@ -324,33 +302,27 @@ public:
 
     virtual Type *toHeadMutable();
     virtual ClassDeclaration *isClassHandle();
-    virtual Expression *getProperty(Loc loc, Identifier *ident, int flag);
-    virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     virtual structalign_t alignment();
-    Expression *noMember(Scope *sc, Expression *e, Identifier *ident, int flag);
-    virtual Expression *defaultInit(Loc loc = Loc());
-    virtual Expression *defaultInitLiteral(Loc loc);
-    virtual bool isZeroInit(Loc loc = Loc());                // if initializer is 0
+    virtual Expression *defaultInitLiteral(const Loc &loc);
+    virtual bool isZeroInit(const Loc &loc = Loc());                // if initializer is 0
     Identifier *getTypeInfoIdent();
-    virtual void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
-    void resolveExp(Expression *e, Type **pt, Expression **pe, Dsymbol **ps);
     virtual int hasWild() const;
     virtual bool hasPointers();
     virtual bool hasVoidInitPointers();
+    virtual bool hasInvariant();
     virtual Type *nextOf();
     Type *baseElemOf();
     uinteger_t sizemask();
-    unsigned numberOfElems(const Loc &loc);
     virtual bool needsDestruction();
+    virtual bool needsCopyOrPostblit();
     virtual bool needsNested();
-    void checkComplexTransition(Loc loc);
-    TypeFunction *toTypeFunction();
 
-    static void error(Loc loc, const char *format, ...);
-    static void warning(Loc loc, const char *format, ...);
+    TypeFunction *toTypeFunction();
 
     // For eliminating dynamic_cast
     virtual TypeBasic *isTypeBasic();
+    TypeFunction *isPtrToFunction();
+    TypeFunction *isFunction_Delegate_PtrToFunction();
     TypeError *isTypeError();
     TypeVector *isTypeVector();
     TypeSArray *isTypeSArray();
@@ -373,6 +345,7 @@ public:
     TypeMixin *isTypeMixin();
     TypeTraits *isTypeTraits();
     TypeNoreturn *isTypeNoreturn();
+    TypeTag *isTypeTag();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -380,14 +353,11 @@ public:
 class TypeError : public Type
 {
 public:
-    TypeError();
-    Type *syntaxCopy();
-
-    d_uns64 size(Loc loc);
-    Expression *getProperty(Loc loc, Identifier *ident, int flag);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
-    Expression *defaultInit(Loc loc);
-    Expression *defaultInitLiteral(Loc loc);
+    const char *kind();
+    TypeError *syntaxCopy();
+
+    d_uns64 size(const Loc &loc);
+    Expression *defaultInitLiteral(const Loc &loc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -396,8 +366,7 @@ class TypeNext : public Type
 public:
     Type *next;
 
-    TypeNext(TY ty, Type *next);
-    void checkDeprecated(Loc loc, Scope *sc);
+    void checkDeprecated(const Loc &loc, Scope *sc);
     int hasWild() const;
     Type *nextOf();
     Type *makeConst();
@@ -421,13 +390,10 @@ public:
     const char *dstring;
     unsigned flags;
 
-    TypeBasic(TY ty);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc) /*const*/;
+    TypeBasic *syntaxCopy();
+    d_uns64 size(const Loc &loc) /*const*/;
     unsigned alignsize();
-    Expression *getProperty(Loc loc, Identifier *ident, int flag);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     bool isintegral();
     bool isfloating() /*const*/;
     bool isreal() /*const*/;
@@ -436,8 +402,7 @@ public:
     bool isscalar() /*const*/;
     bool isunsigned() /*const*/;
     MATCH implicitConvTo(Type *to);
-    Expression *defaultInit(Loc loc);
-    bool isZeroInit(Loc loc) /*const*/;
+    bool isZeroInit(const Loc &loc) /*const*/;
 
     // For eliminating dynamic_cast
     TypeBasic *isTypeBasic();
@@ -449,24 +414,20 @@ class TypeVector : public Type
 public:
     Type *basetype;
 
-    TypeVector(Type *basetype);
     static TypeVector *create(Type *basetype);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc);
+    TypeVector *syntaxCopy();
+    d_uns64 size(const Loc &loc);
     unsigned alignsize();
-    Expression *getProperty(Loc loc, Identifier *ident, int flag);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     bool isintegral();
     bool isfloating();
     bool isscalar();
     bool isunsigned();
     bool isBoolean() /*const*/;
     MATCH implicitConvTo(Type *to);
-    Expression *defaultInit(Loc loc);
-    Expression *defaultInitLiteral(Loc loc);
+    Expression *defaultInitLiteral(const Loc &loc);
     TypeBasic *elementType();
-    bool isZeroInit(Loc loc);
+    bool isZeroInit(const Loc &loc);
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -474,8 +435,6 @@ public:
 class TypeArray : public TypeNext
 {
 public:
-    TypeArray(TY ty, Type *next);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -485,22 +444,20 @@ class TypeSArray : public TypeArray
 public:
     Expression *dim;
 
-    TypeSArray(Type *t, Expression *dim);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc);
+    TypeSArray *syntaxCopy();
+    d_uns64 size(const Loc &loc);
     unsigned alignsize();
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     bool isString();
-    bool isZeroInit(Loc loc);
+    bool isZeroInit(const Loc &loc);
     structalign_t alignment();
     MATCH constConv(Type *to);
     MATCH implicitConvTo(Type *to);
-    Expression *defaultInit(Loc loc);
-    Expression *defaultInitLiteral(Loc loc);
+    Expression *defaultInitLiteral(const Loc &loc);
     bool hasPointers();
+    bool hasInvariant();
     bool needsDestruction();
+    bool needsCopyOrPostblit();
     bool needsNested();
 
     void accept(Visitor *v) { v->visit(this); }
@@ -510,18 +467,14 @@ public:
 class TypeDArray : public TypeArray
 {
 public:
-    TypeDArray(Type *t);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc) /*const*/;
+    TypeDArray *syntaxCopy();
+    d_uns64 size(const Loc &loc) /*const*/;
     unsigned alignsize() /*const*/;
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     bool isString();
-    bool isZeroInit(Loc loc) /*const*/;
+    bool isZeroInit(const Loc &loc) /*const*/;
     bool isBoolean() /*const*/;
     MATCH implicitConvTo(Type *to);
-    Expression *defaultInit(Loc loc);
     bool hasPointers() /*const*/;
 
     void accept(Visitor *v) { v->visit(this); }
@@ -532,17 +485,12 @@ class TypeAArray : public TypeArray
 public:
     Type *index;                // key type
     Loc loc;
-    Scope *sc;
 
-    TypeAArray(Type *t, Type *index);
     static TypeAArray *create(Type *t, Type *index);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc);
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
-    Expression *defaultInit(Loc loc);
-    bool isZeroInit(Loc loc) /*const*/;
+    TypeAArray *syntaxCopy();
+    d_uns64 size(const Loc &loc);
+    bool isZeroInit(const Loc &loc) /*const*/;
     bool isBoolean() /*const*/;
     bool hasPointers() /*const*/;
     MATCH implicitConvTo(Type *to);
@@ -554,16 +502,14 @@ public:
 class TypePointer : public TypeNext
 {
 public:
-    TypePointer(Type *t);
     static TypePointer *create(Type *t);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc) /*const*/;
+    TypePointer *syntaxCopy();
+    d_uns64 size(const Loc &loc) /*const*/;
     MATCH implicitConvTo(Type *to);
     MATCH constConv(Type *to);
     bool isscalar() /*const*/;
-    Expression *defaultInit(Loc loc);
-    bool isZeroInit(Loc loc) /*const*/;
+    bool isZeroInit(const Loc &loc) /*const*/;
     bool hasPointers() /*const*/;
 
     void accept(Visitor *v) { v->visit(this); }
@@ -572,13 +518,10 @@ public:
 class TypeReference : public TypeNext
 {
 public:
-    TypeReference(Type *t);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc) /*const*/;
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
-    Expression *defaultInit(Loc loc);
-    bool isZeroInit(Loc loc) /*const*/;
+    TypeReference *syntaxCopy();
+    d_uns64 size(const Loc &loc) /*const*/;
+    bool isZeroInit(const Loc &loc) /*const*/;
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -588,31 +531,27 @@ enum RET
     RETstack    = 2     // returned on stack
 };
 
-enum TRUST
+enum class TRUST : unsigned char
 {
-    TRUSTdefault = 0,
-    TRUSTsystem = 1,    // @system (same as TRUSTdefault)
-    TRUSTtrusted = 2,   // @trusted
-    TRUSTsafe = 3       // @safe
+    default_ = 0,
+    system = 1,    // @system (same as TRUSTdefault)
+    trusted = 2,   // @trusted
+    safe = 3       // @safe
 };
 
-// in hdrgen.c
-void trustToBuffer(OutBuffer *buf, TRUST trust);
-const char *trustToChars(TRUST trust);
-
 enum TRUSTformat
 {
     TRUSTformatDefault,  // do not emit @system when trust == TRUSTdefault
     TRUSTformatSystem    // emit @system when trust == TRUSTdefault
 };
 
-enum PURE
+enum class PURE : unsigned char
 {
-    PUREimpure = 0,     // not pure at all
-    PUREfwdref = 1,     // it's pure, but not known which level yet
-    PUREweak = 2,       // no mutable globals are read or written
-    PUREconst = 3,      // parameters are values or const
-    PUREstrong = 4      // parameters are values or immutable
+    impure = 0,     // not pure at all
+    fwdref = 1,     // it's pure, but not known which level yet
+    weak = 2,       // no mutable globals are read or written
+    const_ = 3,     // parameters are values or const
+    strong = 4      // parameters are values or immutable
 };
 
 class Parameter : public ASTNode
@@ -624,31 +563,26 @@ public:
     Expression *defaultArg;
     UserAttributeDeclaration *userAttribDecl;   // user defined attributes
 
-    Parameter(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();
     // kludge for template.isType()
-    int dyncast() const { return DYNCAST_PARAMETER; }
+    DYNCAST dyncast() const { return DYNCAST_PARAMETER; }
     void accept(Visitor *v) { v->visit(this); }
 
-    static Parameters *arraySyntaxCopy(Parameters *parameters);
     static size_t dim(Parameters *parameters);
-    static Parameter *getNth(Parameters *parameters, size_t nth, size_t *pn = NULL);
-    const char *toChars();
-    bool isCovariant(bool returnByRef, const Parameter *p) const;
-    static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to);
+    static Parameter *getNth(Parameters *parameters, d_size_t nth);
+    const char *toChars() const;
+    bool isCovariant(bool returnByRef, const Parameter *p, bool previewIn) const;
 };
 
 struct ParameterList
 {
-    Parameters *parameters;
+    Parameters* parameters;
+    StorageClass stc;
     VarArg varargs;
 
-    ParameterList(Parameters *parameters = NULL, VarArg varargs = VARARGnone);
-
     size_t length();
     Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); }
 };
@@ -658,27 +592,17 @@ class TypeFunction : public TypeNext
 public:
     // .next is the return type
 
-    ParameterList parameterList;     // function parameters
-
-    bool isnothrow;     // true: nothrow
-    bool isnogc;        // true: is @nogc
-    bool isproperty;    // can be called without parentheses
-    bool isref;         // true: returns a reference
-    bool isreturn;      // true: 'this' is returned by ref
-    bool isscope;       // true: 'this' is scope
-    bool isscopeinferred; // true: 'this' is scope from inference
-    LINK linkage;  // calling convention
-    TRUST trust;   // level of trust
-    PURE purity;   // PURExxxx
-    unsigned char iswild;   // bit0: inout on params, bit1: inout on qualifier
-    Expressions *fargs; // function arguments
+    ParameterList parameterList; // function parameters
+    LINK linkage;                // calling convention
+    unsigned funcFlags;
+    TRUST trust;                 // level of trust
+    PURE purity;                 // PURExxxx
+    char inuse;
+    Expressions *fargs;          // function arguments
 
-    int inuse;
-
-    TypeFunction(const ParameterList &pl, Type *treturn, LINK linkage, StorageClass stc = 0);
     static TypeFunction *create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc = 0);
     const char *kind();
-    Type *syntaxCopy();
+    TypeFunction *syntaxCopy();
     void purityLevel();
     bool hasLazyParameters();
     bool isDstyleVariadic() const;
@@ -686,15 +610,35 @@ public:
     StorageClass parameterStorageClass(Parameter *p);
     Type *addStorageClass(StorageClass stc);
 
-    /** For each active attribute (ref/const/nogc/etc) call fp with a void* for the
-    work param and a string representation of the attribute. */
-    int attributesApply(void *param, int (*fp)(void *, const char *), TRUSTformat trustFormat = TRUSTformatDefault);
-
     Type *substWildTo(unsigned mod);
-    MATCH callMatch(Type *tthis, Expressions *toargs, int flag = 0, const char **pMessage = NULL);
-    bool checkRetType(Loc loc);
+    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;
 
-    Expression *defaultInit(Loc loc) /*const*/;
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -703,18 +647,15 @@ class TypeDelegate : public TypeNext
 public:
     // .next is a TypeFunction
 
-    TypeDelegate(Type *t);
-    static TypeDelegate *create(Type *t);
+    static TypeDelegate *create(TypeFunction *t);
     const char *kind();
-    Type *syntaxCopy();
+    TypeDelegate *syntaxCopy();
     Type *addStorageClass(StorageClass stc);
-    d_uns64 size(Loc loc) /*const*/;
+    d_uns64 size(const Loc &loc) /*const*/;
     unsigned alignsize() /*const*/;
     MATCH implicitConvTo(Type *to);
-    Expression *defaultInit(Loc loc);
-    bool isZeroInit(Loc loc) /*const*/;
+    bool isZeroInit(const Loc &loc) /*const*/;
     bool isBoolean() /*const*/;
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     bool hasPointers() /*const*/;
 
     void accept(Visitor *v) { v->visit(this); }
@@ -722,33 +663,28 @@ public:
 
 class TypeTraits : public Type
 {
-public:
     Loc loc;
     /// The expression to resolve as type or symbol.
     TraitsExp *exp;
     /// The symbol when exp doesn't represent a type.
     Dsymbol *sym;
 
-    TypeTraits(const Loc &loc, TraitsExp *exp);
-    Type *syntaxCopy();
+    const char *kind();
+    TypeTraits *syntaxCopy();
+    d_uns64 size(const Loc &loc);
     Dsymbol *toDsymbol(Scope *sc);
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
-    d_uns64 size(Loc loc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class TypeMixin : public Type
 {
-public:
     Loc loc;
     Expressions *exps;
     RootObject *obj;
 
-    TypeMixin(const Loc &loc, Expressions *exps);
     const char *kind();
-    Type *syntaxCopy();
+    TypeMixin *syntaxCopy();
     Dsymbol *toDsymbol(Scope *sc);
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -760,17 +696,11 @@ public:
     // representing ident.ident!tiargs.ident. ... etc.
     Objects idents;
 
-    TypeQualified(TY ty, Loc loc);
     void syntaxCopyHelper(TypeQualified *t);
     void addIdent(Identifier *ident);
     void addInst(TemplateInstance *inst);
     void addIndex(RootObject *expr);
-    d_uns64 size(Loc loc);
-
-    void resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
-        Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex);
-    void resolveHelper(Loc loc, Scope *sc, Dsymbol *s, Dsymbol *scopesym,
-        Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
+    d_uns64 size(const Loc &loc);
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -781,10 +711,8 @@ public:
     Identifier *ident;
     Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution
 
-    TypeIdentifier(Loc loc, Identifier *ident);
     const char *kind();
-    Type *syntaxCopy();
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
+    TypeIdentifier *syntaxCopy();
     Dsymbol *toDsymbol(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -796,10 +724,8 @@ class TypeInstance : public TypeQualified
 public:
     TemplateInstance *tempinst;
 
-    TypeInstance(Loc loc, TemplateInstance *tempinst);
     const char *kind();
-    Type *syntaxCopy();
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
+    TypeInstance *syntaxCopy();
     Dsymbol *toDsymbol(Scope *sc);
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -810,23 +736,19 @@ public:
     Expression *exp;
     int inuse;
 
-    TypeTypeof(Loc loc, Expression *exp);
     const char *kind();
-    Type *syntaxCopy();
+    TypeTypeof *syntaxCopy();
     Dsymbol *toDsymbol(Scope *sc);
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
-    d_uns64 size(Loc loc);
+    d_uns64 size(const Loc &loc);
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class TypeReturn : public TypeQualified
 {
 public:
-    TypeReturn(Loc loc);
     const char *kind();
-    Type *syntaxCopy();
+    TypeReturn *syntaxCopy();
     Dsymbol *toDsymbol(Scope *sc);
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -847,26 +769,25 @@ class TypeStruct : public Type
 public:
     StructDeclaration *sym;
     AliasThisRec att;
-    CPPMANGLE cppmangle;
+    bool inuse;
 
-    TypeStruct(StructDeclaration *sym);
     static TypeStruct *create(StructDeclaration *sym);
     const char *kind();
-    d_uns64 size(Loc loc);
+    d_uns64 size(const Loc &loc);
     unsigned alignsize();
-    Type *syntaxCopy();
+    TypeStruct *syntaxCopy();
     Dsymbol *toDsymbol(Scope *sc);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     structalign_t alignment();
-    Expression *defaultInit(Loc loc);
-    Expression *defaultInitLiteral(Loc loc);
-    bool isZeroInit(Loc loc) /*const*/;
+    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);
     unsigned char deduceWild(Type *t, bool isRef);
@@ -880,14 +801,12 @@ class TypeEnum : public Type
 public:
     EnumDeclaration *sym;
 
-    TypeEnum(EnumDeclaration *sym);
     const char *kind();
-    Type *syntaxCopy();
-    d_uns64 size(Loc loc);
+    TypeEnum *syntaxCopy();
+    d_uns64 size(const Loc &loc);
     unsigned alignsize();
+    Type *memType(const Loc &loc = Loc());
     Dsymbol *toDsymbol(Scope *sc);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
-    Expression *getProperty(Loc loc, Identifier *ident, int flag);
     bool isintegral();
     bool isfloating();
     bool isreal();
@@ -899,14 +818,14 @@ public:
     bool isString();
     bool isAssignable();
     bool needsDestruction();
+    bool needsCopyOrPostblit();
     bool needsNested();
     MATCH implicitConvTo(Type *to);
     MATCH constConv(Type *to);
-    Type *toBasetype();
-    Expression *defaultInit(Loc loc);
-    bool isZeroInit(Loc loc);
+    bool isZeroInit(const Loc &loc);
     bool hasPointers();
     bool hasVoidInitPointers();
+    bool hasInvariant();
     Type *nextOf();
 
     void accept(Visitor *v) { v->visit(this); }
@@ -919,20 +838,17 @@ public:
     AliasThisRec att;
     CPPMANGLE cppmangle;
 
-    TypeClass(ClassDeclaration *sym);
     const char *kind();
-    d_uns64 size(Loc loc) /*const*/;
-    Type *syntaxCopy();
+    d_uns64 size(const Loc &loc) /*const*/;
+    TypeClass *syntaxCopy();
     Dsymbol *toDsymbol(Scope *sc);
-    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
     ClassDeclaration *isClassHandle();
     bool isBaseOf(Type *t, int *poffset);
     MATCH implicitConvTo(Type *to);
     MATCH constConv(Type *to);
     unsigned char deduceWild(Type *t, bool isRef);
     Type *toHeadMutable();
-    Expression *defaultInit(Loc loc);
-    bool isZeroInit(Loc loc) /*const*/;
+    bool isZeroInit(const Loc &loc) /*const*/;
     bool isscope() /*const*/;
     bool isBoolean() /*const*/;
     bool hasPointers() /*const*/;
@@ -943,19 +859,18 @@ public:
 class TypeTuple : public Type
 {
 public:
+    // 'logically immutable' cached global - don't modify (neither pointer nor pointee)!
+    static TypeTuple *empty;
+
     Parameters *arguments;      // types making up the tuple
 
-    TypeTuple(Parameters *arguments);
-    TypeTuple(Expressions *exps);
     static TypeTuple *create(Parameters *arguments);
-    TypeTuple();
-    TypeTuple(Type *t1);
-    TypeTuple(Type *t1, Type *t2);
+    static TypeTuple *create();
+    static TypeTuple *create(Type *t1);
+    static TypeTuple *create(Type *t1, Type *t2);
     const char *kind();
-    Type *syntaxCopy();
-    bool equals(RootObject *o);
-    Expression *getProperty(Loc loc, Identifier *ident, int flag);
-    Expression *defaultInit(Loc loc);
+    TypeTuple *syntaxCopy();
+    bool equals(const RootObject *o) const;
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -965,44 +880,49 @@ public:
     Expression *lwr;
     Expression *upr;
 
-    TypeSlice(Type *next, Expression *lwr, Expression *upr);
     const char *kind();
-    Type *syntaxCopy();
-    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
+    TypeSlice *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class TypeNull : public Type
 {
 public:
-    TypeNull();
     const char *kind();
 
-    Type *syntaxCopy();
+    TypeNull *syntaxCopy();
     MATCH implicitConvTo(Type *to);
     bool isBoolean() /*const*/;
 
-    d_uns64 size(Loc loc) /*const*/;
-    Expression *defaultInit(Loc loc) /*const*/;
+    d_uns64 size(const Loc &loc) /*const*/;
     void accept(Visitor *v) { v->visit(this); }
 };
 
-class TypeNoreturn : public Type
+class TypeNoreturn final : public Type
 {
 public:
-    TypeNoreturn();
     const char *kind();
+    TypeNoreturn *syntaxCopy();
+    MATCH implicitConvTo(Type* to);
+    MATCH constConv(Type* to);
+    bool isBoolean() /* const */;
+    d_uns64 size(const Loc& loc) /* const */;
+    unsigned alignsize();
 
-    Type *syntaxCopy();
-    MATCH implicitConvTo(Type *to);
-    bool isBoolean() /*const*/;
+    void accept(Visitor *v) { v->visit(this); }
+};
+
+class TypeTag final : public Type
+{
+public:
+    TypeTag *syntaxCopy();
 
-    d_uns64 size(Loc loc) /*const*/;
-    unsigned alignsize();
     void accept(Visitor *v) { v->visit(this); }
 };
 
 /**************************************************************/
 
-bool arrayTypeCompatible(Loc loc, Type *t1, Type *t2);
 bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2);
+
+// If the type is a class or struct, returns the symbol for it, else null.
+AggregateDeclaration *isAggregate(Type *t);
diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h
index 71dafb2553d..43d36e9e4e0 100644
--- a/gcc/d/dmd/nspace.h
+++ b/gcc/d/dmd/nspace.h
@@ -19,17 +19,13 @@
 class Nspace : public ScopeDsymbol
 {
   public:
-    bool mangleOnly;
-    Nspace(Loc loc, Identifier *ident, Dsymbols *members, bool mangleOnly);
-
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    Expression *identExp;
+    Nspace *syntaxCopy(Dsymbol *s);
     void addMember(Scope *sc, ScopeDsymbol *sds);
     void setScope(Scope *sc);
-    bool oneMember(Dsymbol **ps, Identifier *ident);
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
-    int apply(Dsymbol_apply_ft_t fp, void *param);
     bool hasPointers();
-    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
+    void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
     const char *kind() const;
     Nspace *isNspace() { return this; }
     void accept(Visitor *v) { v->visit(this); }
diff --git a/gcc/d/dmd/objc.h b/gcc/d/dmd/objc.h
index f3da5a3755f..483e50149e7 100644
--- a/gcc/d/dmd/objc.h
+++ b/gcc/d/dmd/objc.h
@@ -10,22 +10,20 @@
 
 #pragma once
 
-#include "root/root.h"
-#include "root/stringtable.h"
+#include "root/dsystem.h"
+#include "arraytypes.h"
 
-class Identifier;
-class FuncDeclaration;
+class AggregateDeclaration;
+class AttribDeclaration;
 class ClassDeclaration;
+class FuncDeclaration;
+class Identifier;
 class InterfaceDeclaration;
+
 struct Scope;
-class StructDeclaration;
 
 struct ObjcSelector
 {
-    static StringTable stringtable;
-    static StringTable vTableDispatchSelectors;
-    static int incnum;
-
     const char *stringvalue;
     size_t stringlen;
     size_t paramCount;
@@ -34,12 +32,29 @@ struct ObjcSelector
 
     ObjcSelector(const char *sv, size_t len, size_t pcount);
 
-    static ObjcSelector *lookup(const char *s);
-    static ObjcSelector *lookup(const char *s, size_t len, size_t pcount);
-
     static ObjcSelector *create(FuncDeclaration *fdecl);
 };
 
+struct ObjcClassDeclaration
+{
+    bool isMeta;
+    bool isExtern;
+
+    Identifier* identifier;
+    ClassDeclaration* classDeclaration;
+    ClassDeclaration* metaclass;
+    DArray<FuncDeclaration*> methodList;
+
+    bool isRootClass() const;
+};
+
+struct ObjcFuncDeclaration
+{
+    ObjcSelector* selector;
+    VarDeclaration* selectorParameter;
+    bool isOptional;
+};
+
 class Objc
 {
 public:
@@ -47,7 +62,23 @@ public:
 
     virtual void setObjc(ClassDeclaration* cd) = 0;
     virtual void setObjc(InterfaceDeclaration*) = 0;
+    virtual const char *toPrettyChars(ClassDeclaration *cd, 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 = 0;
+    virtual void setAsOptional(FuncDeclaration *fd, Scope *sc) const = 0;
+    virtual void validateOptional(FuncDeclaration *fd) const = 0;
+    virtual ClassDeclaration* getParent(FuncDeclaration*, ClassDeclaration*) const = 0;
+    virtual void addToClassMethodList(FuncDeclaration*, ClassDeclaration*) const = 0;
+    virtual AggregateDeclaration* isThis(FuncDeclaration* fd) = 0;
+    virtual VarDeclaration* createSelectorParameter(FuncDeclaration*, Scope*) const = 0;
+
+    virtual void setMetaclass(InterfaceDeclaration* id, Scope*) const = 0;
+    virtual void setMetaclass(ClassDeclaration* id, Scope*) const = 0;
+    virtual ClassDeclaration* getRuntimeMetaclass(ClassDeclaration* cd) = 0;
+
+    virtual void addSymbols(AttribDeclaration*, ClassDeclarations*, ClassDeclarations*) const = 0;
+    virtual void addSymbols(ClassDeclaration*, ClassDeclarations*, ClassDeclarations*) const = 0;
 };
diff --git a/gcc/d/dmd/root/array.h b/gcc/d/dmd/root/array.h
index f7cb0c75184..f573dcaa3ee 100644
--- a/gcc/d/dmd/root/array.h
+++ b/gcc/d/dmd/root/array.h
@@ -9,14 +9,13 @@
 #pragma once
 
 #include "dsystem.h"
-#include "dcompat.h"
 #include "object.h"
 #include "rmem.h"
 
 template <typename TYPE>
 struct Array
 {
-    size_t length;
+    d_size_t length;
 
   private:
     DArray<TYPE> data;
@@ -42,8 +41,8 @@ struct Array
     char *toChars() const
     {
         const char **buf = (const char **)mem.xmalloc(length * sizeof(const char *));
-        size_t len = 2;
-        for (size_t u = 0; u < length; u++)
+        d_size_t len = 2;
+        for (d_size_t u = 0; u < length; u++)
         {
             buf[u] = ((RootObject *)data.ptr[u])->toChars();
             len += strlen(buf[u]) + 1;
@@ -52,7 +51,7 @@ struct Array
 
         str[0] = '[';
         char *p = str + 1;
-        for (size_t u = 0; u < length; u++)
+        for (d_size_t u = 0; u < length; u++)
         {
             if (u)
                 *p++ = ',';
@@ -77,7 +76,7 @@ struct Array
         insert(length, a);
     }
 
-    void reserve(size_t nentries)
+    void reserve(d_size_t nentries)
     {
         //printf("Array::reserve: length = %d, data.length = %d, nentries = %d\n", (int)length, (int)data.length, (int)nentries);
         if (data.length - length < nentries)
@@ -106,7 +105,7 @@ struct Array
             {
                 /* Increase size by 1.5x to avoid excessive memory fragmentation
                  */
-                size_t increment = length / 2;
+                d_size_t increment = length / 2;
                 if (nentries > increment)       // if 1.5 is not enough
                     increment = nentries;
                 data.length = length + increment;
@@ -115,18 +114,18 @@ struct Array
         }
     }
 
-    void remove(size_t i)
+    void remove(d_size_t i)
     {
         if (length - i - 1)
             memmove(data.ptr + i, data.ptr + i + 1, (length - i - 1) * sizeof(TYPE));
         length--;
     }
 
-    void insert(size_t index, Array *a)
+    void insert(d_size_t index, Array *a)
     {
         if (a)
         {
-            size_t d = a->length;
+            d_size_t d = a->length;
             reserve(d);
             if (length != index)
                 memmove(data.ptr + index + d, data.ptr + index, (length - index) * sizeof(TYPE));
@@ -135,7 +134,7 @@ struct Array
         }
     }
 
-    void insert(size_t index, TYPE ptr)
+    void insert(d_size_t index, TYPE ptr)
     {
         reserve(1);
         memmove(data.ptr + index + 1, data.ptr + index, (length - index) * sizeof(TYPE));
@@ -143,7 +142,7 @@ struct Array
         length++;
     }
 
-    void setDim(size_t newdim)
+    void setDim(d_size_t newdim)
     {
         if (length < newdim)
         {
@@ -152,9 +151,9 @@ struct Array
         length = newdim;
     }
 
-    size_t find(TYPE ptr) const
+    d_size_t find(TYPE ptr) const
     {
-        for (size_t i = 0; i < length; i++)
+        for (d_size_t i = 0; i < length; i++)
         {
             if (data.ptr[i] == ptr)
                 return i;
@@ -167,7 +166,7 @@ struct Array
         return find(ptr) != SIZE_MAX;
     }
 
-    TYPE& operator[] (size_t index)
+    TYPE& operator[] (d_size_t index)
     {
 #ifdef DEBUG
         assert(index < length);
@@ -205,28 +204,5 @@ struct Array
     {
         return data.ptr[--length];
     }
-
-    void sort()
-    {
-        struct ArraySort
-        {
-            static int
-    #if _WIN32
-              __cdecl
-    #endif
-            Array_sort_compare(const void *x, const void *y)
-            {
-                RootObject *ox = *(RootObject **)const_cast<void *>(x);
-                RootObject *oy = *(RootObject **)const_cast<void *>(y);
-
-                return ox->compare(oy);
-            }
-        };
-
-        if (length)
-        {
-            qsort(data.ptr, length, sizeof(RootObject *), &ArraySort::Array_sort_compare);
-        }
-    }
 };
 
diff --git a/gcc/d/dmd/root/bitarray.h b/gcc/d/dmd/root/bitarray.h
index 004c43caa54..e773711e7f5 100644
--- a/gcc/d/dmd/root/bitarray.h
+++ b/gcc/d/dmd/root/bitarray.h
@@ -24,8 +24,8 @@ struct BitArray
         mem.xfree(ptr);
     }
 
-    size_t len;
-    size_t *ptr;
+    d_size_t len;
+    d_size_t *ptr;
 
 private:
     BitArray(const BitArray&);
diff --git a/gcc/d/dmd/root/ctfloat.h b/gcc/d/dmd/root/ctfloat.h
index 0a829f3e051..1221b822188 100644
--- a/gcc/d/dmd/root/ctfloat.h
+++ b/gcc/d/dmd/root/ctfloat.h
@@ -1,5 +1,6 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
@@ -16,9 +17,6 @@ typedef longdouble real_t;
 // Compile-time floating-point helper
 struct CTFloat
 {
-    static bool yl2x_supported;
-    static bool yl2xp1_supported;
-
     static void yl2x(const real_t *x, const real_t *y, real_t *res);
     static void yl2xp1(const real_t *x, const real_t *y, real_t *res);
 
@@ -62,4 +60,6 @@ struct CTFloat
     static real_t one;
     static real_t minusone;
     static real_t half;
+
+    static void initialize();
 };
diff --git a/gcc/d/dmd/root/dcompat.h b/gcc/d/dmd/root/dcompat.h
index 9fd176ebcb1..88f20952cc9 100644
--- a/gcc/d/dmd/root/dcompat.h
+++ b/gcc/d/dmd/root/dcompat.h
@@ -34,3 +34,15 @@ struct DString : public DArray<const char>
     DString(size_t length, const char *ptr)
         : DArray<const char>(length, ptr) { }
 };
+
+/// Corresponding C++ type that maps to D size_t
+#if __APPLE__ && __i386__
+// size_t is 'unsigned long', which makes it mangle differently than D's 'uint'
+typedef unsigned d_size_t;
+#elif MARS && DMD_VERSION >= 2079 && DMD_VERSION <= 2081 && \
+        __APPLE__ && __SIZEOF_SIZE_T__ == 8
+// DMD versions between 2.079 and 2.081 mapped D ulong to uint64_t on OS X.
+typedef uint64_t d_size_t;
+#else
+typedef size_t d_size_t;
+#endif
diff --git a/gcc/d/dmd/root/file.h b/gcc/d/dmd/root/file.h
index 51358182b7c..ee0d51e105c 100644
--- a/gcc/d/dmd/root/file.h
+++ b/gcc/d/dmd/root/file.h
@@ -1,5 +1,6 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
@@ -8,46 +9,33 @@
 
 #pragma once
 
-#include "dsystem.h"
 #include "array.h"
+#include "filename.h"
 
-typedef Array<struct File *> Files;
-
-struct FileName;
-
-struct File
+struct FileBuffer
 {
-    int ref;                    // != 0 if this is a reference to someone else's buffer
-    unsigned char *buffer;      // data for our file
-    size_t len;                 // amount of data in buffer[]
-
-    FileName *name;             // name of our file
-
-    File(const char *);
-    static File *create(const char *);
-    File(const FileName *);
-    ~File();
-
-    const char *toChars();
+    DArray<unsigned char> data;
 
-    /* Read file, return true if error
-     */
+    FileBuffer(const FileBuffer &) /* = delete */;
+    ~FileBuffer() { mem.xfree(data.ptr); }
 
-    bool read();
-
-    /* Write file, return true if error
-     */
+    static FileBuffer *create();
+};
 
-    bool write();
+struct File
+{
+    struct ReadResult
+    {
+        bool success;
+        FileBuffer buffer;
+    };
 
-    /* Set buffer
-     */
+    // Read the full content of a file.
+    static ReadResult read(const char *name);
 
-    void setbuffer(void *buffer, size_t len)
-    {
-        this->buffer = (unsigned char *)buffer;
-        this->len = len;
-    }
+    // Write a file, returning `true` on success.
+    static bool write(const char *name, const void *data, d_size_t size);
 
-    void remove();              // delete file
+    // Delete a file.
+    static void remove(const char *name);
 };
diff --git a/gcc/d/dmd/root/filename.h b/gcc/d/dmd/root/filename.h
index 52cd963d708..9f773b5bb99 100644
--- a/gcc/d/dmd/root/filename.h
+++ b/gcc/d/dmd/root/filename.h
@@ -1,5 +1,6 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
@@ -9,20 +10,16 @@
 #pragma once
 
 #include "array.h"
+#include "dcompat.h"
 
-class RootObject;
-
-template <typename TYPE> struct Array;
 typedef Array<const char *> Strings;
 
 struct FileName
 {
-    const char *str;
-    FileName(const char *str);
-    bool equals(RootObject *obj);
+private:
+    DString str;
+public:
     static bool equals(const char *name1, const char *name2);
-    int compare(RootObject *obj);
-    static int compare(const char *name1, const char *name2);
     static bool absolute(const char *name);
     static const char *toAbsolute(const char *name, const char *base = NULL);
     static const char *ext(const char *);
@@ -31,7 +28,6 @@ struct FileName
     static const char *name(const char *);
     const char *name();
     static const char *path(const char *);
-    static const char *replaceName(const char *path, const char *name);
 
     static const char *combine(const char *path, const char *name);
     static Strings *splitPath(const char *path);
@@ -42,7 +38,6 @@ struct FileName
     bool equalsExt(const char *ext);
 
     static const char *searchPath(Strings *path, const char *name, bool cwd);
-    static const char *safeSearchPath(Strings *path, const char *name);
     static int exists(const char *name);
     static bool ensurePathExists(const char *path);
     static const char *canonicalName(const char *name);
diff --git a/gcc/d/dmd/root/object.h b/gcc/d/dmd/root/object.h
index d5e3b2b090d..fb367bc1649 100644
--- a/gcc/d/dmd/root/object.h
+++ b/gcc/d/dmd/root/object.h
@@ -1,14 +1,16 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
- * https://github.com/dlang/dmd/blob/master/src/root/object.h
+ * http://www.boost.org/LICENSE_1_0.txt
+ * https://github.com/dlang/dmd/blob/master/src/dmd/root/object.h
  */
 
 #pragma once
 
 #include "dsystem.h"
+#include "dcompat.h"
 
 typedef size_t hash_t;
 
@@ -23,7 +25,8 @@ enum DYNCAST
     DYNCAST_IDENTIFIER,
     DYNCAST_TUPLE,
     DYNCAST_PARAMETER,
-    DYNCAST_STATEMENT
+    DYNCAST_STATEMENT,
+    DYNCAST_TEMPLATEPARAMETER
 };
 
 /*
@@ -34,25 +37,19 @@ class RootObject
 public:
     RootObject() { }
 
-    virtual bool equals(RootObject *o);
-
-    /**
-     * Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.
-     * Useful for sorting Objects.
-     */
-    virtual int compare(RootObject *obj);
+    virtual bool equals(const RootObject *o) const;
 
     /**
      * Pretty-print an Object. Useful for debugging the old-fashioned way.
      */
-    virtual void print();
-
-    virtual const char *toChars();
-    virtual void toBuffer(OutBuffer *buf);
+    virtual const char *toChars() const;
+    /// This function is `extern(D)` and should not be called from C++,
+    /// as the ABI does not match on some platforms
+    virtual DString toString();
 
     /**
      * Used as a replacement for dynamic_cast. Returns a unique number
      * defined by the library user. For Object, the return value is 0.
      */
-    virtual int dyncast() const;
+    virtual DYNCAST dyncast() const;
 };
diff --git a/gcc/d/dmd/root/outbuffer.h b/gcc/d/dmd/root/outbuffer.h
index 186fbb7eb84..b635373c183 100644
--- a/gcc/d/dmd/root/outbuffer.h
+++ b/gcc/d/dmd/root/outbuffer.h
@@ -1,5 +1,6 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
@@ -16,14 +17,16 @@ class RootObject;
 
 struct OutBuffer
 {
+    // IMPORTANT: PLEASE KEEP STATE AND DESTRUCTOR IN SYNC WITH DEFINITION IN ./outbuffer.d.
 private:
     DArray<unsigned char> data;
-    size_t offset;
+    d_size_t offset;
     bool notlinehead;
+    void* fileMapping;  // pointer to a file mapping object not used on the C++ side
 public:
-
-    int level;
     bool doindent;
+    bool spaces;
+    int level;
 
     OutBuffer()
     {
@@ -33,17 +36,18 @@ public:
         doindent = 0;
         level = 0;
         notlinehead = 0;
+        fileMapping = 0;
     }
     ~OutBuffer()
     {
         mem.xfree(data.ptr);
     }
-    const DArray<unsigned char> slice() const { return data; }
-    size_t length() const { return offset; }
+    d_size_t length() const { return offset; }
     char *extractData();
+    void destroy();
 
-    void reserve(size_t nbytes);
-    void setsize(size_t size);
+    void reserve(d_size_t nbytes);
+    void setsize(d_size_t size);
     void reset();
     void write(const void *data, size_t nbytes);
     void writestring(const char *string);
@@ -56,17 +60,16 @@ public:
     void writeword(unsigned w);
     void writeUTF16(unsigned w);
     void write4(unsigned w);
-    void write(OutBuffer *buf);
+    void write(const OutBuffer *buf);
     void write(RootObject *obj);
-    void fill0(size_t nbytes);
+    void fill0(d_size_t nbytes);
     void vprintf(const char *format, va_list args);
     void printf(const char *format, ...);
-    void print(unsigned long long u);
     void bracket(char left, char right);
-    size_t bracket(size_t i, const char *left, size_t j, const char *right);
-    void spread(size_t offset, size_t nbytes);
-    size_t insert(size_t offset, const void *data, size_t nbytes);
-    void remove(size_t offset, size_t nbytes);
+    d_size_t bracket(d_size_t i, const char *left, d_size_t j, const char *right);
+    void spread(d_size_t offset, d_size_t nbytes);
+    d_size_t insert(d_size_t offset, const void *data, d_size_t nbytes);
+    void remove(d_size_t offset, d_size_t nbytes);
     // Append terminating null if necessary and get view of internal buffer
     char *peekChars();
     // Append terminating null if necessary and take ownership of data
diff --git a/gcc/d/dmd/root/port.h b/gcc/d/dmd/root/port.h
index 94651cdd5a4..08cf66cf10e 100644
--- a/gcc/d/dmd/root/port.h
+++ b/gcc/d/dmd/root/port.h
@@ -1,5 +1,6 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
@@ -11,15 +12,7 @@
 // Portable wrapper around compiler/system specific things.
 // The idea is to minimize #ifdef's in the app code.
 
-#include "dsystem.h" // for alloca
-
-#if _MSC_VER
-typedef __int64 longlong;
-typedef unsigned __int64 ulonglong;
-#else
-typedef long long longlong;
-typedef unsigned long long ulonglong;
-#endif
+#include "dsystem.h"
 
 typedef unsigned char utf8_t;
 
diff --git a/gcc/d/dmd/root/rmem.h b/gcc/d/dmd/root/rmem.h
index 1f603b8c658..04d9e3fb9a2 100644
--- a/gcc/d/dmd/root/rmem.h
+++ b/gcc/d/dmd/root/rmem.h
@@ -1,5 +1,6 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
@@ -8,19 +9,25 @@
 
 #pragma once
 
-#include "dsystem.h"    // for size_t
+#include "dcompat.h"    // for d_size_t
 
 struct Mem
 {
     Mem() { }
 
     static char *xstrdup(const char *s);
-    static void *xmalloc(size_t size);
-    static void *xcalloc(size_t size, size_t n);
-    static void *xrealloc(void *p, size_t size);
     static void xfree(void *p);
-    static void *xmallocdup(void *o, size_t size);
+    static void *xmalloc(d_size_t size);
+    static void *xcalloc(d_size_t size, d_size_t n);
+    static void *xrealloc(void *p, d_size_t size);
     static void error();
+
+    static bool _isGCEnabled;
+
+    static bool isGCEnabled();
+    static void disableGC();
+    static void addRange(const void *p, d_size_t size);
+    static void removeRange(const void *p);
 };
 
 extern Mem mem;
diff --git a/gcc/d/dmd/root/root.h b/gcc/d/dmd/root/root.h
index d998d95be76..667ce67fb7c 100644
--- a/gcc/d/dmd/root/root.h
+++ b/gcc/d/dmd/root/root.h
@@ -1,5 +1,6 @@
 
 /* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
+ * written by Walter Bright
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index ea3061b8fa6..4d8c0bbef18 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -10,8 +10,6 @@
 
 #pragma once
 
-class Dsymbol;
-class ScopeDsymbol;
 class Identifier;
 class Module;
 class Statement;
@@ -26,49 +24,48 @@ class UserAttributeDeclaration;
 struct DocComment;
 struct AA;
 class TemplateInstance;
+class CPPNamespaceDeclaration;
 
 #include "dsymbol.h"
 
-#if __GNUC__
-// Requires a full definition for LINK
-#include "globals.h"
-#else
-enum LINK;
-enum PINLINE;
-#endif
-
-#define CSXthis_ctor    1       // called this()
-#define CSXsuper_ctor   2       // called super()
-#define CSXthis         4       // referenced this
-#define CSXsuper        8       // referenced super
-#define CSXlabel        0x10    // seen a label
-#define CSXreturn       0x20    // seen a return statement
-#define CSXany_ctor     0x40    // either this() or super() was called
-#define CSXhalt         0x80    // assert(0)
-
-// Flags that would not be inherited beyond scope nesting
-#define SCOPEctor           0x0001  // constructor type
-#define SCOPEcondition      0x0004  // inside static if/assert condition
-#define SCOPEdebug          0x0008  // inside debug conditional
-
-// Flags that would be inherited beyond scope nesting
-#define SCOPEnoaccesscheck  0x0002  // don't do access checks
-#define SCOPEconstraint     0x0010  // inside template constraint
-#define SCOPEinvariant      0x0020  // inside invariant code
-#define SCOPErequire        0x0040  // inside in contract code
-#define SCOPEensure         0x0060  // inside out contract code
-#define SCOPEcontract       0x0060  // [mask] we're inside contract code
-#define SCOPEctfe           0x0080  // inside a ctfe-only expression
-#define SCOPEcompile        0x0100  // inside __traits(compile)
-#define SCOPEignoresymbolvisibility 0x0200  // ignore symbol visibility (Bugzilla 15907)
-
-#define SCOPEfree           0x8000  // is on free list
-#define SCOPEfullinst       0x10000 // fully instantiate templates
-#define SCOPEalias          0x20000 // inside alias declaration
-
-// The following are mutually exclusive
-#define SCOPEprintf         0x40000 // printf-style function
-#define SCOPEscanf          0x80000 // scanf-style function
+enum
+{
+    CSXthis_ctor  = 1,      // called this()
+    CSXsuper_ctor = 2,      // called super()
+    CSXthis       = 4,      // referenced this
+    CSXsuper      = 8,      // referenced super
+    CSXlabel      = 0x10,   // seen a label
+    CSXreturn     = 0x20,   // seen a return statement
+    CSXany_ctor   = 0x40,   // either this() or super() was called
+    CSXhalt       = 0x80,   // assert(0)
+};
+
+enum
+{
+    // Flags that would not be inherited beyond scope nesting
+    SCOPEctor          = 0x0001,  // constructor type
+    SCOPEcondition     = 0x0004,  // inside static if/assert condition
+    SCOPEdebug         = 0x0008,  // inside debug conditional
+
+    // Flags that would be inherited beyond scope nesting
+    SCOPEnoaccesscheck = 0x0002,  // don't do access checks
+    SCOPEconstraint    = 0x0010,  // inside template constraint
+    SCOPEinvariant     = 0x0020,  // inside invariant code
+    SCOPErequire       = 0x0040,  // inside in contract code
+    SCOPEensure        = 0x0060,  // inside out contract code
+    SCOPEcontract      = 0x0060,  // [mask] we're inside contract code
+    SCOPEctfe          = 0x0080,  // inside a ctfe-only expression
+    SCOPEcompile       = 0x0100,  // inside __traits(compile)
+    SCOPEignoresymbolvisibility = 0x0200,  // ignore symbol visibility (Bugzilla 15907)
+
+    SCOPEfree          = 0x8000,  // is on free list
+    SCOPEfullinst      = 0x10000, // fully instantiate templates
+    SCOPEalias         = 0x20000, // inside alias declaration
+
+    // The following are mutually exclusive
+    SCOPEprintf        = 0x40000, // printf-style function
+    SCOPEscanf         = 0x80000, // scanf-style function
+};
 
 struct Scope
 {
@@ -80,15 +77,16 @@ struct Scope
     Dsymbol *parent;            // parent to use
     LabelStatement *slabel;     // enclosing labelled statement
     SwitchStatement *sw;        // enclosing switch statement
+    Statement *tryBody;         // enclosing _body of TryCatchStatement or TryFinallyStatement
     TryFinallyStatement *tf;    // enclosing try finally statement
     ScopeGuardStatement *os;       // enclosing scope(xxx) statement
     Statement *sbreak;          // enclosing statement that supports "break"
     Statement *scontinue;       // enclosing statement that supports "continue"
     ForeachStatement *fes;      // if nested function for ForeachStatement, this is it
     Scope *callsc;              // used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__
-    int inunion;                // we're processing members of a union
-    int nofree;                 // set if shouldn't free it
-    int noctor;                 // set if constructor calls aren't allowed
+    Dsymbol *inunion;           // !=null if processing members of a union
+    bool nofree;                // true if shouldn't free it
+    bool inLoop;                // true if inside a loop (where constructor calls aren't allowed)
     int intypeof;               // in typeof(exp)
     VarDeclaration *lastVar;    // Previous symbol used to prevent goto-skips-init
 
@@ -100,18 +98,21 @@ struct Scope
     Module *minst;              // root module where the instantiated templates should belong to
     TemplateInstance *tinst;    // enclosing template instance
 
-    unsigned callSuper;         // primitive flow analysis for constructors
-    unsigned *fieldinit;
+    unsigned char callSuper;    // primitive flow analysis for constructors
+    unsigned char *fieldinit;
     size_t fieldinit_dim;
 
     AlignDeclaration *aligndecl;    // alignment for struct members
 
+    /// C++ namespace this symbol belongs to
+    CPPNamespaceDeclaration *namespace_;
+
     LINK linkage;               // linkage for external functions
     CPPMANGLE cppmangle;        // C++ mangle type
-    PINLINE inlining;            // inlining strategy for functions
+    PragmaDeclaration *inlining; // inlining strategy for functions
 
-    Prot protection;            // protection for class members
-    int explicitProtection;     // set if in an explicit protection attribute
+    Visibility visibility;            // visibility for class members
+    int explicitVisibility;     // set if in an explicit visibility attribute
 
     StorageClass stc;           // storage class
 
@@ -125,10 +126,8 @@ struct Scope
     AA *anchorCounts;           // lookup duplicate anchor name count
     Identifier *prevAnchor;     // qualified symbol name of last doc anchor
 
-    static Scope *freelist;
-    static Scope *alloc();
-    static Scope *createGlobal(Module *module);
-
+    AliasDeclaration *aliasAsg; // if set, then aliasAsg is being assigned a new value,
+                                // do not set wasRead for it
     Scope();
 
     Scope *copy();
@@ -140,21 +139,12 @@ struct Scope
     Scope *startCTFE();
     Scope *endCTFE();
 
-    void mergeCallSuper(Loc loc, unsigned cs);
-
-    unsigned *saveFieldInit();
-    void mergeFieldInit(Loc loc, unsigned *cses);
-
-    Module *instantiatingModule();
-
-    Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone);
-    Dsymbol *search_correct(Identifier *ident);
-    static const char *search_correct_C(Identifier *ident);
-    Dsymbol *insert(Dsymbol *s);
+    Dsymbol *search(const Loc &loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone);
 
     ClassDeclaration *getClassScope();
     AggregateDeclaration *getStructClassScope();
-    void setNoFree();
 
     structalign_t alignment();
+
+    bool isDeprecated() const;
 };
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index c64e51a5be7..7825762db9e 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -10,27 +10,21 @@
 
 #pragma once
 
-#include "root/root.h"
-
 #include "arraytypes.h"
 #include "ast_node.h"
 #include "dsymbol.h"
 #include "visitor.h"
 #include "tokens.h"
 
-struct OutBuffer;
 struct Scope;
 class Expression;
 class LabelDsymbol;
 class Identifier;
-class Statement;
 class IfStatement;
 class ExpStatement;
 class DefaultStatement;
 class VarDeclaration;
 class Condition;
-class Module;
-struct Token;
 class ErrorStatement;
 class ReturnStatement;
 class CompoundStatement;
@@ -39,7 +33,6 @@ class StaticAssert;
 class AsmStatement;
 class GotoStatement;
 class ScopeStatement;
-class Catch;
 class TryCatchStatement;
 class TryFinallyStatement;
 class CaseStatement;
@@ -50,14 +43,6 @@ class StaticForeach;
 // Back end
 struct code;
 
-Statement *statementSemantic(Statement *s, Scope *sc);
-Statement *semanticNoScope(Statement *s, Scope *sc);
-Statement *semanticScope(Statement *s, Scope *sc, Statement *sbreak, Statement *scontinue);
-void catchSemantic(Catch *c, Scope *sc);
-
-bool inferAggregate(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);
-bool inferApplyArgTypes(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);
-
 /* How a statement exits; this is returned by blockExit()
  */
 enum BE
@@ -74,46 +59,106 @@ enum BE
     BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt)
 };
 
+typedef unsigned char STMT;
+enum
+{
+    STMTerror,
+    STMTpeel,
+    STMTexp, STMTdtorExp,
+    STMTcompile,
+    STMTcompound, STMTcompoundDeclaration, STMTcompoundAsm,
+    STMTunrolledLoop,
+    STMTscope,
+    STMTforwarding,
+    STMTwhile,
+    STMTdo,
+    STMTfor,
+    STMTforeach,
+    STMTforeachRange,
+    STMTif,
+    STMTconditional,
+    STMTstaticForeach,
+    STMTpragma,
+    STMTstaticAssert,
+    STMTswitch,
+    STMTcase,
+    STMTcaseRange,
+    STMTdefault,
+    STMTgotoDefault,
+    STMTgotoCase,
+    STMTswitchError,
+    STMTreturn,
+    STMTbreak,
+    STMTcontinue,
+    STMTsynchronized,
+    STMTwith,
+    STMTtryCatch,
+    STMTtryFinally,
+    STMTscopeGuard,
+    STMTthrow,
+    STMTdebug,
+    STMTgoto,
+    STMTlabel,
+    STMTasm, STMTinlineAsm, STMTgccAsm,
+    STMTimport
+};
+
 class Statement : public ASTNode
 {
 public:
     Loc loc;
+    STMT stmt;
 
-    Statement(Loc loc);
     virtual Statement *syntaxCopy();
-    static Statements *arraySyntaxCopy(Statements *a);
 
-    void print();
-    const char *toChars();
+    const char *toChars() const;
 
     void error(const char *format, ...);
     void warning(const char *format, ...);
     void deprecation(const char *format, ...);
     virtual Statement *getRelatedLabeled() { return this; }
-    virtual bool hasBreak();
-    virtual bool hasContinue();
+    virtual bool hasBreak() const;
+    virtual bool hasContinue() const;
     bool usesEH();
     bool comeFrom();
     bool hasCode();
-    virtual Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
-    virtual Statements *flatten(Scope *sc);
     virtual Statement *last();
 
-    // Avoid dynamic_cast
-    virtual ErrorStatement *isErrorStatement() { return NULL; }
-    virtual ScopeStatement *isScopeStatement() { return NULL; }
-    virtual ExpStatement *isExpStatement() { return NULL; }
-    virtual CompoundStatement *isCompoundStatement() { return NULL; }
-    virtual ReturnStatement *isReturnStatement() { return NULL; }
-    virtual IfStatement *isIfStatement() { return NULL; }
-    virtual CaseStatement *isCaseStatement() { return NULL; }
-    virtual DefaultStatement *isDefaultStatement() { return NULL; }
-    virtual LabelStatement *isLabelStatement() { return NULL; }
-    virtual GotoDefaultStatement *isGotoDefaultStatement() { return NULL; }
-    virtual GotoCaseStatement *isGotoCaseStatement() { return NULL; }
-    virtual BreakStatement *isBreakStatement() { return NULL; }
-    virtual DtorExpStatement *isDtorExpStatement() { return NULL; }
-    virtual ForwardingStatement *isForwardingStatement() { return NULL; }
+    virtual ReturnStatement *endsWithReturnStatement() { return NULL; }
+
+    ErrorStatement       *isErrorStatement()       { return stmt == STMTerror       ? (ErrorStatement*)this       : NULL; }
+    ScopeStatement       *isScopeStatement()       { return stmt == STMTscope       ? (ScopeStatement*)this       : NULL; }
+    ExpStatement         *isExpStatement()         { return stmt == STMTexp         ? (ExpStatement*)this         : NULL; }
+    CompoundStatement    *isCompoundStatement()    { return stmt == STMTcompound    ? (CompoundStatement*)this    : NULL; }
+    ReturnStatement      *isReturnStatement()      { return stmt == STMTreturn      ? (ReturnStatement*)this      : NULL; }
+    IfStatement          *isIfStatement()          { return stmt == STMTif          ? (IfStatement*)this          : NULL; }
+    ConditionalStatement *isConditionalStatement() { return stmt == STMTconditional ? (ConditionalStatement*)this : NULL; }
+    StaticForeachStatement *isStaticForeachStatement() { return stmt == STMTstaticForeach ? (StaticForeachStatement*)this : NULL; }
+    CaseStatement        *isCaseStatement()        { return stmt == STMTcase        ? (CaseStatement*)this        : NULL; }
+    DefaultStatement     *isDefaultStatement()     { return stmt == STMTdefault     ? (DefaultStatement*)this     : NULL; }
+    LabelStatement       *isLabelStatement()       { return stmt == STMTlabel       ? (LabelStatement*)this       : NULL; }
+    GotoDefaultStatement *isGotoDefaultStatement() { return stmt == STMTgotoDefault ? (GotoDefaultStatement*)this : NULL; }
+    GotoCaseStatement    *isGotoCaseStatement()    { return stmt == STMTgotoCase    ? (GotoCaseStatement*)this    : NULL; }
+    BreakStatement       *isBreakStatement()       { return stmt == STMTbreak       ? (BreakStatement*)this       : NULL; }
+    DtorExpStatement     *isDtorExpStatement()     { return stmt == STMTdtorExp     ? (DtorExpStatement*)this     : NULL; }
+    CompileStatement     *isCompileStatement()     { return stmt == STMTcompile     ? (CompileStatement*)this     : NULL; }
+    ForwardingStatement  *isForwardingStatement()  { return stmt == STMTforwarding  ? (ForwardingStatement*)this  : NULL; }
+    DoStatement          *isDoStatement()          { return stmt == STMTdo          ? (DoStatement*)this          : NULL; }
+    ForStatement         *isForStatement()         { return stmt == STMTfor         ? (ForStatement*)this         : NULL; }
+    ForeachStatement     *isForeachStatement()     { return stmt == STMTforeach     ? (ForeachStatement*)this     : NULL; }
+    SwitchStatement      *isSwitchStatement()      { return stmt == STMTswitch      ? (SwitchStatement*)this      : NULL; }
+    ContinueStatement    *isContinueStatement()    { return stmt == STMTcontinue    ? (ContinueStatement*)this    : NULL; }
+    WithStatement        *isWithStatement()        { return stmt == STMTwith        ? (WithStatement*)this        : NULL; }
+    TryCatchStatement    *isTryCatchStatement()    { return stmt == STMTtryCatch    ? (TryCatchStatement*)this    : NULL; }
+    ThrowStatement       *isThrowStatement()       { return stmt == STMTthrow       ? (ThrowStatement*)this       : NULL; }
+    DebugStatement       *isDebugStatement()       { return stmt == STMTdebug       ? (DebugStatement*)this       : NULL; }
+    TryFinallyStatement  *isTryFinallyStatement()  { return stmt == STMTtryFinally  ? (TryFinallyStatement*)this  : NULL; }
+    ScopeGuardStatement  *isScopeGuardStatement()  { return stmt == STMTscopeGuard  ? (ScopeGuardStatement*)this  : NULL; }
+    SwitchErrorStatement  *isSwitchErrorStatement()  { return stmt == STMTswitchError  ? (SwitchErrorStatement*)this  : NULL; }
+    UnrolledLoopStatement *isUnrolledLoopStatement() { return stmt == STMTunrolledLoop ? (UnrolledLoopStatement*)this : NULL; }
+    ForeachRangeStatement *isForeachRangeStatement() { return stmt == STMTforeachRange ? (ForeachRangeStatement*)this : NULL; }
+    CompoundDeclarationStatement *isCompoundDeclarationStatement() { return stmt == STMTcompoundDeclaration ? (CompoundDeclarationStatement*)this : NULL; }
+
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -123,10 +168,8 @@ public:
 class ErrorStatement : public Statement
 {
 public:
-    ErrorStatement();
-    Statement *syntaxCopy();
+    ErrorStatement *syntaxCopy();
 
-    ErrorStatement *isErrorStatement() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -135,7 +178,6 @@ class PeelStatement : public Statement
 public:
     Statement *s;
 
-    PeelStatement(Statement *s);
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -144,14 +186,9 @@ class ExpStatement : public Statement
 public:
     Expression *exp;
 
-    ExpStatement(Loc loc, Expression *exp);
-    ExpStatement(Loc loc, Dsymbol *s);
     static ExpStatement *create(Loc loc, Expression *exp);
-    Statement *syntaxCopy();
-    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
-    Statements *flatten(Scope *sc);
+    ExpStatement *syntaxCopy();
 
-    ExpStatement *isExpStatement() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -163,11 +200,8 @@ public:
 
     VarDeclaration *var;
 
-    DtorExpStatement(Loc loc, Expression *exp, VarDeclaration *v);
-    Statement *syntaxCopy();
+    DtorExpStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
-
-    DtorExpStatement *isDtorExpStatement() { return this; }
 };
 
 class CompileStatement : public Statement
@@ -175,10 +209,7 @@ class CompileStatement : public Statement
 public:
     Expressions *exps;
 
-    CompileStatement(Loc loc, Expression *exp);
-    CompileStatement(Loc loc, Expressions *exps);
-    Statement *syntaxCopy();
-    Statements *flatten(Scope *sc);
+    CompileStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -187,24 +218,18 @@ class CompoundStatement : public Statement
 public:
     Statements *statements;
 
-    CompoundStatement(Loc loc, Statements *s);
-    CompoundStatement(Loc loc, Statement *s1);
-    CompoundStatement(Loc loc, Statement *s1, Statement *s2);
     static CompoundStatement *create(Loc loc, Statement *s1, Statement *s2);
-    Statement *syntaxCopy();
-    Statements *flatten(Scope *sc);
-    ReturnStatement *isReturnStatement();
+    CompoundStatement *syntaxCopy();
+    ReturnStatement *endsWithReturnStatement();
     Statement *last();
 
-    CompoundStatement *isCompoundStatement() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class CompoundDeclarationStatement : public CompoundStatement
 {
 public:
-    CompoundDeclarationStatement(Loc loc, Statements *s);
-    Statement *syntaxCopy();
+    CompoundDeclarationStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -216,10 +241,9 @@ class UnrolledLoopStatement : public Statement
 public:
     Statements *statements;
 
-    UnrolledLoopStatement(Loc loc, Statements *statements);
-    Statement *syntaxCopy();
-    bool hasBreak();
-    bool hasContinue();
+    UnrolledLoopStatement *syntaxCopy();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -230,12 +254,10 @@ public:
     Statement *statement;
     Loc endloc;                 // location of closing curly bracket
 
-    ScopeStatement(Loc loc, Statement *s, Loc endloc);
-    Statement *syntaxCopy();
-    ScopeStatement *isScopeStatement() { return this; }
-    ReturnStatement *isReturnStatement();
-    bool hasBreak();
-    bool hasContinue();
+    ScopeStatement *syntaxCopy();
+    ReturnStatement *endsWithReturnStatement();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -246,25 +268,21 @@ public:
     ForwardingScopeDsymbol *sym;
     Statement *statement;
 
-    ForwardingStatement(Loc loc, ForwardingScopeDsymbol *sym, Statement *s);
-    ForwardingStatement(Loc loc, Statement *s);
-    Statement *syntaxCopy();
-    Statements *flatten(Scope *sc);
-    ForwardingStatement *isForwardingStatement() { return this; }
+    ForwardingStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
 class WhileStatement : public Statement
 {
 public:
+    Parameter *param;
     Expression *condition;
     Statement *_body;
     Loc endloc;                 // location of closing curly bracket
 
-    WhileStatement(Loc loc, Expression *c, Statement *b, Loc endloc);
-    Statement *syntaxCopy();
-    bool hasBreak();
-    bool hasContinue();
+    WhileStatement *syntaxCopy();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -276,10 +294,9 @@ public:
     Expression *condition;
     Loc endloc;                 // location of ';' after while
 
-    DoStatement(Loc loc, Statement *b, Expression *c, Loc endloc);
-    Statement *syntaxCopy();
-    bool hasBreak();
-    bool hasContinue();
+    DoStatement *syntaxCopy();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -298,12 +315,10 @@ public:
     // treat that label as referring to this loop.
     Statement *relatedLabeled;
 
-    ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body, Loc endloc);
-    Statement *syntaxCopy();
-    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
+    ForStatement *syntaxCopy();
     Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; }
-    bool hasBreak();
-    bool hasContinue();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -325,11 +340,9 @@ public:
     Statements *cases;          // put breaks, continues, gotos and returns here
     ScopeStatements *gotos;     // forward referenced goto's go here
 
-    ForeachStatement(Loc loc, TOK op, Parameters *parameters, Expression *aggr, Statement *body, Loc endloc);
-    Statement *syntaxCopy();
-    bool checkForArgTypes();
-    bool hasBreak();
-    bool hasContinue();
+    ForeachStatement *syntaxCopy();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -346,11 +359,9 @@ public:
 
     VarDeclaration *key;
 
-    ForeachRangeStatement(Loc loc, TOK op, Parameter *prm,
-        Expression *lwr, Expression *upr, Statement *body, Loc endloc);
-    Statement *syntaxCopy();
-    bool hasBreak();
-    bool hasContinue();
+    ForeachRangeStatement *syntaxCopy();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -362,13 +373,10 @@ public:
     Expression *condition;
     Statement *ifbody;
     Statement *elsebody;
-    Loc endloc;                 // location of closing curly bracket
-
     VarDeclaration *match;      // for MatchExpression results
+    Loc endloc;                 // location of closing curly bracket
 
-    IfStatement(Loc loc, Parameter *prm, Expression *condition, Statement *ifbody, Statement *elsebody, Loc endloc);
-    Statement *syntaxCopy();
-    IfStatement *isIfStatement() { return this; }
+    IfStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -380,9 +388,7 @@ public:
     Statement *ifbody;
     Statement *elsebody;
 
-    ConditionalStatement(Loc loc, Condition *condition, Statement *ifbody, Statement *elsebody);
-    Statement *syntaxCopy();
-    Statements *flatten(Scope *sc);
+    ConditionalStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -392,9 +398,7 @@ class StaticForeachStatement : public Statement
 public:
     StaticForeach *sfe;
 
-    StaticForeachStatement(Loc loc, StaticForeach *sfe);
-    Statement *syntaxCopy();
-    Statements *flatten(Scope *sc);
+    StaticForeachStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -406,8 +410,7 @@ public:
     Expressions *args;          // array of Expression's
     Statement *_body;
 
-    PragmaStatement(Loc loc, Identifier *ident, Expressions *args, Statement *body);
-    Statement *syntaxCopy();
+    PragmaStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -417,8 +420,7 @@ class StaticAssertStatement : public Statement
 public:
     StaticAssert *sa;
 
-    StaticAssertStatement(StaticAssert *sa);
-    Statement *syntaxCopy();
+    StaticAssertStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -431,6 +433,7 @@ public:
     bool isFinal;
 
     DefaultStatement *sdefault;
+    Statement *tryBody;            // set to TryCatchStatement or TryFinallyStatement if in _body portion
     TryFinallyStatement *tf;
     GotoCaseStatements gotoCases;  // array of unresolved GotoCaseStatement's
     CaseStatements *cases;         // array of CaseStatement's
@@ -438,10 +441,8 @@ public:
     int hasVars;                // !=0 if has variable case values
     VarDeclaration *lastVar;
 
-    SwitchStatement(Loc loc, Expression *c, Statement *b, bool isFinal);
-    Statement *syntaxCopy();
-    bool hasBreak();
-    bool checkLabel();
+    SwitchStatement *syntaxCopy();
+    bool hasBreak() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -454,11 +455,9 @@ public:
 
     int index;          // which case it is (since we sort this)
     VarDeclaration *lastVar;
+    void* extra;            // for use by Statement_toIR()
 
-    CaseStatement(Loc loc, Expression *exp, Statement *s);
-    Statement *syntaxCopy();
-    int compare(RootObject *obj);
-    CaseStatement *isCaseStatement() { return this; }
+    CaseStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -471,8 +470,7 @@ public:
     Expression *last;
     Statement *statement;
 
-    CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s);
-    Statement *syntaxCopy();
+    CaseRangeStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -483,9 +481,7 @@ public:
     Statement *statement;
     VarDeclaration *lastVar;
 
-    DefaultStatement(Loc loc, Statement *s);
-    Statement *syntaxCopy();
-    DefaultStatement *isDefaultStatement() { return this; }
+    DefaultStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -495,9 +491,7 @@ class GotoDefaultStatement : public Statement
 public:
     SwitchStatement *sw;
 
-    GotoDefaultStatement(Loc loc);
-    Statement *syntaxCopy();
-    GotoDefaultStatement *isGotoDefaultStatement() { return this; }
+    GotoDefaultStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -508,9 +502,7 @@ public:
     Expression *exp;            // NULL, or which case to goto
     CaseStatement *cs;          // case statement it resolves to
 
-    GotoCaseStatement(Loc loc, Expression *exp);
-    Statement *syntaxCopy();
-    GotoCaseStatement *isGotoCaseStatement() { return this; }
+    GotoCaseStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -518,7 +510,7 @@ public:
 class SwitchErrorStatement : public Statement
 {
 public:
-    SwitchErrorStatement(Loc loc);
+    Expression *exp;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -529,10 +521,9 @@ public:
     Expression *exp;
     size_t caseDim;
 
-    ReturnStatement(Loc loc, Expression *exp);
-    Statement *syntaxCopy();
+    ReturnStatement *syntaxCopy();
 
-    ReturnStatement *isReturnStatement() { return this; }
+    ReturnStatement *endsWithReturnStatement() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -541,10 +532,8 @@ class BreakStatement : public Statement
 public:
     Identifier *ident;
 
-    BreakStatement(Loc loc, Identifier *ident);
-    Statement *syntaxCopy();
+    BreakStatement *syntaxCopy();
 
-    BreakStatement *isBreakStatement() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -553,8 +542,7 @@ class ContinueStatement : public Statement
 public:
     Identifier *ident;
 
-    ContinueStatement(Loc loc, Identifier *ident);
-    Statement *syntaxCopy();
+    ContinueStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -565,10 +553,9 @@ public:
     Expression *exp;
     Statement *_body;
 
-    SynchronizedStatement(Loc loc, Expression *exp, Statement *body);
-    Statement *syntaxCopy();
-    bool hasBreak();
-    bool hasContinue();
+    SynchronizedStatement *syntaxCopy();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -581,8 +568,7 @@ public:
     VarDeclaration *wthis;
     Loc endloc;
 
-    WithStatement(Loc loc, Expression *exp, Statement *body, Loc endloc);
-    Statement *syntaxCopy();
+    WithStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -593,9 +579,10 @@ public:
     Statement *_body;
     Catches *catches;
 
-    TryCatchStatement(Loc loc, Statement *body, Catches *catches);
-    Statement *syntaxCopy();
-    bool hasBreak();
+    Statement *tryBody;   /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
+
+    TryCatchStatement *syntaxCopy();
+    bool hasBreak() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -606,9 +593,9 @@ public:
     Loc loc;
     Type *type;
     Identifier *ident;
-    VarDeclaration *var;
     Statement *handler;
 
+    VarDeclaration *var;
     // set if semantic processing errors
     bool errors;
 
@@ -616,7 +603,6 @@ public:
     // wasn't present in source code
     bool internalCatch;
 
-    Catch(Loc loc, Type *t, Identifier *id, Statement *handler);
     Catch *syntaxCopy();
 };
 
@@ -626,11 +612,13 @@ public:
     Statement *_body;
     Statement *finalbody;
 
-    TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody);
+    Statement *tryBody;   // set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
+    bool bodyFallsThru;   // true if _body falls through to finally
+
     static TryFinallyStatement *create(Loc loc, Statement *body, Statement *finalbody);
-    Statement *syntaxCopy();
-    bool hasBreak();
-    bool hasContinue();
+    TryFinallyStatement *syntaxCopy();
+    bool hasBreak() const;
+    bool hasContinue() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -641,9 +629,7 @@ public:
     TOK tok;
     Statement *statement;
 
-    ScopeGuardStatement(Loc loc, TOK tok, Statement *statement);
-    Statement *syntaxCopy();
-    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
+    ScopeGuardStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -656,8 +642,7 @@ public:
     // wasn't present in source code
     bool internalThrow;
 
-    ThrowStatement(Loc loc, Expression *exp);
-    Statement *syntaxCopy();
+    ThrowStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -667,9 +652,7 @@ class DebugStatement : public Statement
 public:
     Statement *statement;
 
-    DebugStatement(Loc loc, Statement *statement);
-    Statement *syntaxCopy();
-    Statements *flatten(Scope *sc);
+    DebugStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -678,13 +661,12 @@ class GotoStatement : public Statement
 public:
     Identifier *ident;
     LabelDsymbol *label;
+    Statement *tryBody;   /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
     TryFinallyStatement *tf;
     ScopeGuardStatement *os;
     VarDeclaration *lastVar;
 
-    GotoStatement(Loc loc, Identifier *ident);
-    Statement *syntaxCopy();
-    bool checkLabel();
+    GotoStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -694,19 +676,15 @@ class LabelStatement : public Statement
 public:
     Identifier *ident;
     Statement *statement;
+    Statement *tryBody;   /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
     TryFinallyStatement *tf;
     ScopeGuardStatement *os;
     VarDeclaration *lastVar;
     Statement *gotoTarget;      // interpret
-
+    void* extra;                // used by Statement_toIR()
     bool breaks;                // someone did a 'break ident'
 
-    LabelStatement(Loc loc, Identifier *ident, Statement *statement);
-    Statement *syntaxCopy();
-    Statements *flatten(Scope *sc);
-    Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally);
-
-    LabelStatement *isLabelStatement() { return this; }
+    LabelStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -716,7 +694,9 @@ class LabelDsymbol : public Dsymbol
 public:
     LabelStatement *statement;
 
-    LabelDsymbol(Identifier *ident);
+    bool deleted;           // set if rewritten to return in foreach delegate
+    bool iasm;              // set if used by inline assembler
+
     static LabelDsymbol *create(Identifier *ident);
     LabelDsymbol *isLabel();
     void accept(Visitor *v) { v->visit(this); }
@@ -729,8 +709,7 @@ class AsmStatement : public Statement
 public:
     Token *tokens;
 
-    AsmStatement(Loc loc, Token *tokens);
-    Statement *syntaxCopy();
+    AsmStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -743,8 +722,7 @@ public:
     bool refparam;              // true if function parameter is referenced
     bool naked;                 // true if function is to be naked
 
-    InlineAsmStatement(Loc loc, Token *tokens);
-    Statement *syntaxCopy();
+    InlineAsmStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -762,8 +740,7 @@ public:
     Identifiers *labels;        // list of goto labels
     GotoStatements *gotos;      // of the goto labels, the equivalent statements they represent
 
-    GccAsmStatement(Loc loc, Token *tokens);
-    Statement *syntaxCopy();
+    GccAsmStatement *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -773,9 +750,7 @@ class CompoundAsmStatement : public CompoundStatement
 public:
     StorageClass stc; // postfix attributes like nothrow/pure/@trusted
 
-    CompoundAsmStatement(Loc loc, Statements *s, StorageClass stc);
     CompoundAsmStatement *syntaxCopy();
-    Statements *flatten(Scope *sc);
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -785,8 +760,7 @@ class ImportStatement : public Statement
 public:
     Dsymbols *imports;          // Array of Import's
 
-    ImportStatement(Loc loc, Dsymbols *imports);
-    Statement *syntaxCopy();
+    ImportStatement *syntaxCopy();
 
     void accept(Visitor *v) { v->visit(this); }
 };
diff --git a/gcc/d/dmd/staticassert.h b/gcc/d/dmd/staticassert.h
index 6d43cb73a0d..8f880804454 100644
--- a/gcc/d/dmd/staticassert.h
+++ b/gcc/d/dmd/staticassert.h
@@ -5,7 +5,7 @@
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/dlang/dmd/blob/master/src/staticassert.h
+ * https://github.com/dlang/dmd/blob/master/src/dmd/staticassert.h
  */
 
 #pragma once
@@ -20,9 +20,7 @@ public:
     Expression *exp;
     Expression *msg;
 
-    StaticAssert(Loc loc, Expression *exp, Expression *msg);
-
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    StaticAssert *syntaxCopy(Dsymbol *s);
     void addMember(Scope *sc, ScopeDsymbol *sds);
     bool oneMember(Dsymbol **ps, Identifier *ident);
     const char *kind() const;
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index f8f977c9aea..83281a6358f 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -23,22 +23,75 @@ class FuncDeclaration;
 class Parameter;
 class Statement;
 class Type;
-class TypeFunction;
 class TypeTuple;
-struct OutBuffer;
+class TypeFunction;
+
+enum class CPU
+{
+    x87,
+    mmx,
+    sse,
+    sse2,
+    sse3,
+    ssse3,
+    sse4_1,
+    sse4_2,
+    avx,                // AVX1 instruction set
+    avx2,               // AVX2 instruction set
+    avx512,             // AVX-512 instruction set
+
+    // Special values that don't survive past the command line processing
+    baseline,           // (default) the minimum capability CPU
+    native              // the machine the compiler is being run on
+};
 
 struct TargetC
 {
-    unsigned longsize;            // size of a C 'long' or 'unsigned long' type
-    unsigned long_doublesize;     // size of a C 'long double'
-    Type *twchar_t;               // C 'wchar_t' type
+    enum class Runtime : unsigned char
+    {
+        Unspecified,
+        Bionic,
+        DigitalMars,
+        Glibc,
+        Microsoft,
+        Musl,
+        Newlib,
+        UClibc,
+        WASI,
+    };
+
+    enum class BitFieldStyle : unsigned char
+    {
+        Unspecified,
+        Dm_Ms,                // Digital Mars and Microsoft C compilers
+                              // https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160
+                              // https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
+        Gcc_Clang,            // gcc and clang
+    };
+
+    uint8_t longsize;            // size of a C 'long' or 'unsigned long' type
+    uint8_t long_doublesize;     // size of a C 'long double'
+    uint8_t wchar_tsize;         // size of a C 'wchar_t' type
+    Runtime runtime;
+    BitFieldStyle bitFieldStyle; // different C compilers do it differently
 };
 
 struct TargetCPP
 {
+    enum class Runtime : unsigned char
+    {
+        Unspecified,
+        Clang,
+        DigitalMars,
+        Gcc,
+        Microsoft,
+        Sun
+    };
     bool reverseOverloads;    // with dmc and cl, overloaded functions are grouped and in reverse order
     bool exceptions;          // set if catching C++ exceptions is supported
     bool twoDtorInVtable;     // target C++ ABI puts deleting and non-deleting destructor into vtable
+    bool wrapDtorInExternD;   // set if C++ dtors require a D wrapper to be callable from runtime
+    Runtime runtime;
 
     const char *toMangle(Dsymbol *s);
     const char *typeInfoMangle(ClassDeclaration *cd);
@@ -56,13 +109,35 @@ struct TargetObjC
 
 struct Target
 {
+    typedef unsigned char OS;
+    enum
+    {
+        /* These are mutually exclusive; one and only one is set.
+         * Match spelling and casing of corresponding version identifiers
+         */
+        OS_Freestanding = 0,
+        OS_linux        = 1,
+        OS_Windows      = 2,
+        OS_OSX          = 4,
+        OS_OpenBSD      = 8,
+        OS_FreeBSD      = 0x10,
+        OS_Solaris      = 0x20,
+        OS_DragonFlyBSD = 0x40,
+
+        // Combination masks
+        all = OS_linux | OS_Windows | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD,
+        Posix = OS_linux | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD,
+    };
+
+    OS os;
+    uint8_t osMajor;
     // D ABI
-    unsigned ptrsize;
-    unsigned realsize;           // size a real consumes in memory
-    unsigned realpad;            // 'padding' added to the CPU real size to bring it up to realsize
-    unsigned realalignsize;      // alignment for reals
-    unsigned classinfosize;      // size of 'ClassInfo'
-    unsigned long long maxStaticDataSize;  // maximum size of static data
+    uint8_t ptrsize;
+    uint8_t realsize;           // size a real consumes in memory
+    uint8_t realpad;            // 'padding' added to the CPU real size to bring it up to realsize
+    uint8_t realalignsize;      // alignment for reals
+    uint8_t classinfosize;      // size of 'ClassInfo'
+    uint64_t maxStaticDataSize; // maximum size of static data
 
     // C ABI
     TargetC c;
@@ -73,13 +148,24 @@ struct Target
     // Objective-C ABI
     TargetObjC objc;
 
+    DString architectureName;    // name of the platform architecture (e.g. X86_64)
+    CPU cpu;                // CPU instruction set to target
+    bool is64bit;           // generate 64 bit code for x86_64; true by default for 64 bit dmd
+    bool isLP64;            // pointers are 64 bits
+
+    // Environmental
+    DString obj_ext;    /// extension for object files
+    DString lib_ext;    /// extension for static library files
+    DString dll_ext;    /// extension for dynamic library files
+    bool run_noext;     /// allow -run sources without extensions
+    bool mscoff;        /// for Win32: write COFF object files instead of OMF
+
     template <typename T>
     struct FPTypeProperties
     {
         real_t max;
         real_t min_normal;
         real_t nan;
-        real_t snan;
         real_t infinity;
         real_t epsilon;
 
@@ -97,21 +183,27 @@ struct Target
 
 private:
     Type *tvalist;
+    const Param *params;
 
 public:
     void _init(const Param& params);
     // Type sizes and support.
+    void setTriple(const char* _triple);
     unsigned alignsize(Type *type);
     unsigned fieldalign(Type *type);
     Type *va_listType(const Loc &loc, Scope *sc);  // get type of va_list
     int isVectorTypeSupported(int sz, Type *type);
-    bool isVectorOpSupported(Type *type, TOK op, Type *t2 = NULL);
+    bool isVectorOpSupported(Type *type, unsigned op, Type *t2 = NULL);
     // ABI and backend.
     LINK systemLinkage();
     TypeTuple *toArgTypes(Type *t);
     bool isReturnOnStack(TypeFunction *tf, bool needsThis);
+    d_uns64 parameterSize(const Loc& loc, Type *t);
+    bool preferPassByRef(Type *t);
     Expression *getTargetInfo(const char* name, const Loc& loc);
+    bool isCalleeDestroyingArgs(TypeFunction* tf);
     bool libraryObjectMonitors(FuncDeclaration *fd, Statement *fbody);
+    void addPredefinedGlobalIdentifiers() const;
 };
 
 extern Target target;
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 086ec72ba60..08ce9acef99 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -10,12 +10,9 @@
 
 #pragma once
 
-#include "root/root.h"
 #include "arraytypes.h"
 #include "dsymbol.h"
 
-
-struct OutBuffer;
 class Identifier;
 class TemplateInstance;
 class TemplateParameter;
@@ -26,18 +23,10 @@ class TemplateAliasParameter;
 class TemplateTupleParameter;
 class Type;
 class TypeQualified;
-class TypeTypeof;
 struct Scope;
 class Expression;
-class AliasDeclaration;
 class FuncDeclaration;
 class Parameter;
-enum MATCH;
-enum PASS;
-
-bool tpsemantic(TemplateParameter *tp, Scope *sc, TemplateParameters *parameters);
-RootObject *aliasParameterSemantic(Loc loc, Scope *sc, RootObject *o, TemplateParameters *parameters);
-void templateInstanceSemantic(TemplateInstance *tempinst, Scope *sc, Expressions *fargs);
 
 class Tuple : public RootObject
 {
@@ -45,9 +34,9 @@ public:
     Objects objects;
 
     // kludge for template.isType()
-    int dyncast() const { return DYNCAST_TUPLE; }
+    DYNCAST dyncast() const { return DYNCAST_TUPLE; }
 
-    const char *toChars() { return objects.toChars(); }
+    const char *toChars() const { return objects.toChars(); }
 };
 
 struct TemplatePrevious
@@ -78,38 +67,29 @@ public:
     bool ismixin;               // template declaration is only to be used as a mixin
     bool isstatic;              // this is static template declaration
     bool isTrivialAliasSeq;     // matches `template AliasSeq(T...) { alias AliasSeq = T; }
-    bool isTrivialAlias;        // matches `template Alias(T) { alias Alias = T; }
-    Prot protection;
+    bool isTrivialAlias;        // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
+    bool deprecated_;           // this template declaration is deprecated
+    Visibility visibility;
     int inuse;                  // for recursive expansion detection
 
     TemplatePrevious *previous;         // threaded list of previous instantiation attempts on stack
 
-    TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
-        Expression *constraint, Dsymbols *decldefs, bool ismixin = false, bool literal = false);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    TemplateDeclaration *syntaxCopy(Dsymbol *);
     bool overloadInsert(Dsymbol *s);
     bool hasStaticCtorOrDtor();
     const char *kind() const;
-    const char *toChars();
-
-    Prot prot();
+    const char *toChars() const;
 
-    bool evaluateConstraint(TemplateInstance *ti, Scope *sc, Scope *paramscope, Objects *dedtypes, FuncDeclaration *fd);
+    Visibility visible();
 
-    MATCH matchWithInstance(Scope *sc, TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag);
     MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);
-
-    MATCH deduceFunctionTemplateMatch(TemplateInstance *ti, Scope *sc, FuncDeclaration *&fd, Type *tthis, Expressions *fargs);
     RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
-    FuncDeclaration *doHeaderInstantiation(TemplateInstance *ti, Scope *sc, FuncDeclaration *fd, Type *tthis, Expressions *fargs);
-    TemplateInstance *findExistingInstance(TemplateInstance *tithis, Expressions *fargs);
-    TemplateInstance *addInstance(TemplateInstance *ti);
-    void removeInstance(TemplateInstance *handle);
 
     TemplateDeclaration *isTemplateDeclaration() { return this; }
 
     TemplateTupleParameter *isVariadic();
-    bool isOverloadable();
+    bool isDeprecated() const;
+    bool isOverloadable() const;
 
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -141,8 +121,6 @@ public:
      */
     bool dependent;
 
-    TemplateParameter(Loc loc, Identifier *ident);
-
     virtual TemplateTypeParameter  *isTemplateTypeParameter();
     virtual TemplateValueParameter *isTemplateValueParameter();
     virtual TemplateAliasParameter *isTemplateAliasParameter();
@@ -156,14 +134,9 @@ public:
     virtual RootObject *defaultArg(Loc instLoc, Scope *sc) = 0;
     virtual bool hasDefaultArg() = 0;
 
-    /* Match actual argument against parameter.
-     */
-    virtual MATCH matchArg(Loc instLoc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
-    virtual MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
-
     /* Create dummy argument based on parameter.
      */
-    virtual void *dummyArg() = 0;
+    virtual RootObject *dummyArg() = 0;
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -172,24 +145,18 @@ public:
  */
 class TemplateTypeParameter : public TemplateParameter
 {
-    using TemplateParameter::matchArg;
 public:
     Type *specType;     // type parameter: if !=NULL, this is the type specialization
     Type *defaultType;
 
-    static Type *tdummy;
-
-    TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
-
     TemplateTypeParameter *isTemplateTypeParameter();
-    TemplateParameter *syntaxCopy();
+    TemplateTypeParameter *syntaxCopy();
     bool declareParameter(Scope *sc);
     void print(RootObject *oarg, RootObject *oded);
     RootObject *specialization();
     RootObject *defaultArg(Loc instLoc, Scope *sc);
     bool hasDefaultArg();
-    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
-    void *dummyArg();
+    RootObject *dummyArg();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -199,10 +166,8 @@ public:
 class TemplateThisParameter : public TemplateTypeParameter
 {
 public:
-    TemplateThisParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
-
     TemplateThisParameter *isTemplateThisParameter();
-    TemplateParameter *syntaxCopy();
+    TemplateThisParameter *syntaxCopy();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -211,25 +176,19 @@ public:
  */
 class TemplateValueParameter : public TemplateParameter
 {
-    using TemplateParameter::matchArg;
 public:
     Type *valType;
     Expression *specValue;
     Expression *defaultValue;
 
-    static AA *edummies;
-
-    TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
-
     TemplateValueParameter *isTemplateValueParameter();
-    TemplateParameter *syntaxCopy();
+    TemplateValueParameter *syntaxCopy();
     bool declareParameter(Scope *sc);
     void print(RootObject *oarg, RootObject *oded);
     RootObject *specialization();
     RootObject *defaultArg(Loc instLoc, Scope *sc);
     bool hasDefaultArg();
-    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
-    void *dummyArg();
+    RootObject *dummyArg();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -238,25 +197,19 @@ public:
  */
 class TemplateAliasParameter : public TemplateParameter
 {
-    using TemplateParameter::matchArg;
 public:
     Type *specType;
     RootObject *specAlias;
     RootObject *defaultAlias;
 
-    static Dsymbol *sdummy;
-
-    TemplateAliasParameter(Loc loc, Identifier *ident, Type *specType, RootObject *specAlias, RootObject *defaultAlias);
-
     TemplateAliasParameter *isTemplateAliasParameter();
-    TemplateParameter *syntaxCopy();
+    TemplateAliasParameter *syntaxCopy();
     bool declareParameter(Scope *sc);
     void print(RootObject *oarg, RootObject *oded);
     RootObject *specialization();
     RootObject *defaultArg(Loc instLoc, Scope *sc);
     bool hasDefaultArg();
-    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
-    void *dummyArg();
+    RootObject *dummyArg();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -266,18 +219,14 @@ public:
 class TemplateTupleParameter : public TemplateParameter
 {
 public:
-    TemplateTupleParameter(Loc loc, Identifier *ident);
-
     TemplateTupleParameter *isTemplateTupleParameter();
-    TemplateParameter *syntaxCopy();
+    TemplateTupleParameter *syntaxCopy();
     bool declareParameter(Scope *sc);
     void print(RootObject *oarg, RootObject *oded);
     RootObject *specialization();
     RootObject *defaultArg(Loc instLoc, Scope *sc);
     bool hasDefaultArg();
-    MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
-    MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
-    void *dummyArg();
+    RootObject *dummyArg();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -300,16 +249,14 @@ public:
     // [int, char, 100]
     Objects tdtypes;
 
+    // Modules imported by this template instance
+    Modules importedModules;
+
     Dsymbol *tempdecl;                  // referenced by foo.bar.abc
     Dsymbol *enclosing;                 // if referencing local symbols, this is the context
     Dsymbol *aliasdecl;                 // !=NULL if instance is an alias for its sole member
     TemplateInstance *inst;             // refer to existing instance
     ScopeDsymbol *argsym;               // argument symbol table
-    int inuse;                          // for recursive expansion detection
-    int nest;                           // for recursive pretty printing detection
-    bool semantictiargsdone;            // has semanticTiargs() been done?
-    bool havetempdecl;                  // if used second constructor
-    bool gagged;                        // if the instantiation is done with error gagging
     hash_t hash;                        // cached result of toHash()
     Expressions *fargs;                 // for function template, these are the function arguments
 
@@ -323,37 +270,22 @@ public:
     TemplateInstance *tnext;            // non-first instantiated instances
     Module *minst;                      // the top module that instantiated this instance
 
-    TemplateInstance(Loc loc, Identifier *temp_id);
-    TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
-    static Objects *arraySyntaxCopy(Objects *objs);
-    Dsymbol *syntaxCopy(Dsymbol *);
+private:
+    unsigned short _nest;                // for recursive pretty printing detection, 3 MSBs reserved for flags
+public:
+    unsigned char inuse;                 // for recursive expansion detection
+
+    TemplateInstance *syntaxCopy(Dsymbol *);
     Dsymbol *toAlias();                 // resolve real symbol
     const char *kind() const;
     bool oneMember(Dsymbol **ps, Identifier *ident);
-    const char *toChars();
+    const char *toChars() const;
     const char* toPrettyCharsHelper();
-    void printInstantiationTrace();
     Identifier *getIdent();
-    int compare(RootObject *o);
     hash_t toHash();
 
     bool needsCodegen();
 
-    // Internal
-    bool findTempDecl(Scope *sc, WithScopeSymbol **pwithsym);
-    bool updateTempDecl(Scope *sc, Dsymbol *s);
-    static bool semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags);
-    bool semanticTiargs(Scope *sc);
-    bool findBestMatch(Scope *sc, Expressions *fargs);
-    bool needsTypeInference(Scope *sc, int flag = 0);
-    bool hasNestedArgs(Objects *tiargs, bool isstatic);
-    Dsymbols *appendToModuleMember();
-    void declareParameters(Scope *sc);
-    Identifier *genIdent(Objects *args);
-    void expandMembers(Scope *sc);
-    void tryExpandMembers(Scope *sc);
-    void trySemantic3(Scope *sc2);
-
     TemplateInstance *isTemplateInstance() { return this; }
     void accept(Visitor *v) { v->visit(this); }
 };
@@ -363,16 +295,12 @@ class TemplateMixin : public TemplateInstance
 public:
     TypeQualified *tqual;
 
-    TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs);
-    Dsymbol *syntaxCopy(Dsymbol *s);
+    TemplateMixin *syntaxCopy(Dsymbol *s);
     const char *kind() const;
     bool oneMember(Dsymbol **ps, Identifier *ident);
-    int apply(Dsymbol_apply_ft_t fp, void *param);
     bool hasPointers();
-    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
-    const char *toChars();
-
-    bool findTempDecl(Scope *sc);
+    void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
+    const char *toChars() const;
 
     TemplateMixin *isTemplateMixin() { return this; }
     void accept(Visitor *v) { v->visit(this); }
@@ -383,9 +311,5 @@ Dsymbol *isDsymbol(RootObject *o);
 Type *isType(RootObject *o);
 Tuple *isTuple(RootObject *o);
 Parameter *isParameter(RootObject *o);
-bool arrayObjectIsError(Objects *args);
-bool isError(RootObject *o);
-Type *getType(RootObject *o);
-Dsymbol *getDsymbol(RootObject *o);
-
-RootObject *objectSyntaxCopy(RootObject *o);
+TemplateParameter *isTemplateParameter(RootObject *o);
+bool isError(const RootObject *const o);
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index f79d8419c90..0fd6634f2ce 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -10,6 +10,7 @@
 
 #pragma once
 
+#include "root/dcompat.h"
 #include "root/port.h"
 #include "globals.h"
 
@@ -31,7 +32,8 @@ class Identifier;
         ?       &&      ||
  */
 
-enum TOK
+typedef unsigned short TOK;
+enum
 {
         TOKreserved,
 
@@ -76,15 +78,10 @@ enum TOK
         TOKindex,       TOKis,
 
 // 64
-        // NCEG floating point compares
-        // !<>=     <>    <>=    !>     !>=   !<     !<=   !<>
-        TOKunord,TOKlg,TOKleg,TOKule,TOKul,TOKuge,TOKug,TOKue,
-
-// 72
         TOKshl,         TOKshr,
         TOKshlass,      TOKshrass,
         TOKushr,        TOKushrass,
-        TOKcat,         TOKcatass,      // ~ ~=
+        TOKcat,         TOKcatass,      TOKcatelemass,  TOKcatdcharass,     // ~ ~=
         TOKadd,         TOKmin,         TOKaddass,      TOKminass,
         TOKmul,         TOKdiv,         TOKmod,
         TOKmulass,      TOKdivass,      TOKmodass,
@@ -92,11 +89,11 @@ enum TOK
         TOKandass,      TOKorass,       TOKxorass,
         TOKassign,      TOKnot,         TOKtilde,
         TOKplusplus,    TOKminusminus,  TOKconstruct,   TOKblit,
-        TOKdot,         TOKarrow,       TOKcomma,
+        TOKdot,         TOKcomma,
         TOKquestion,    TOKandand,      TOKoror,
         TOKpreplusplus, TOKpreminusminus,
 
-// 111
+// 105
         // Numeric literals
         TOKint32v, TOKuns32v,
         TOKint64v, TOKuns64v,
@@ -125,7 +122,7 @@ enum TOK
         TOKcomplex32, TOKcomplex64, TOKcomplex80,
         TOKchar, TOKwchar, TOKdchar, TOKbool,
 
-// 158
+// 152
         // Aggregates
         TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,
         TOKalias, TOKoverride, TOKdelegate, TOKfunction,
@@ -134,8 +131,9 @@ enum TOK
         TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
         TOKstatic, TOKfinal, TOKconst, TOKabstract,
         TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
-        TOKauto, TOKpackage, TOKmanifest, TOKimmutable,
+        TOKauto, TOKpackage, TOKimmutable,
 
+// 182
         // Statements
         TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
         TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,
@@ -144,6 +142,7 @@ enum TOK
         TOKscope,
         TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,
 
+// 206
         // Contracts
         TOKinvariant,
 
@@ -155,6 +154,7 @@ enum TOK
         TOKref,
         TOKmacro,
 
+// 211
         TOKparameters,
         TOKtraits,
         TOKoverloadset,
@@ -175,12 +175,42 @@ enum TOK
         TOKvector,
         TOKpound,
 
+// 230
         TOKinterval,
         TOKvoidexp,
         TOKcantexp,
+        TOKshowctfecontext,
 
+        TOKobjc_class_reference,
         TOKvectorarray,
 
+        TOKarrow,
+        TOKcolonColon,
+        TOKwchar_tLiteral,
+
+        TOKinline,
+        TOKregister,
+        TOKrestrict,
+        TOKsigned,
+        TOKsizeof_,
+        TOKtypedef_,
+        TOKunsigned,
+        TOKvolatile,
+        TOK_Alignas,
+        TOK_Alignof,
+        TOK_Atomic,
+        TOK_Bool,
+        TOK_Complex,
+        TOK_Generic,
+        TOK_Imaginary,
+        TOK_Noreturn,
+        TOK_Static_assert,
+        TOK_Thread_local,
+
+        TOK__cdecl,
+        TOK__declspec,
+        TOK__attribute__,
+
         TOKMAX
 };
 
@@ -196,15 +226,15 @@ struct Token
 {
     Token *next;
     Loc loc;
-    const utf8_t *ptr;         // pointer to first character of this token within buffer
+    const utf8_t *ptr;    // pointer to first character of this token within buffer
     TOK value;
-    const utf8_t *blockComment; // doc comment string prior to this token
-    const utf8_t *lineComment;  // doc comment for previous token
+    DString blockComment; // doc comment string prior to this token
+    DString lineComment;  // doc comment for previous token
     union
     {
         // Integers
-        d_int64 int64value;
-        d_uns64 uns64value;
+        sinteger_t intvalue;
+        uinteger_t unsvalue;
 
         // Floats
         real_t floatvalue;
@@ -218,16 +248,13 @@ struct Token
         Identifier *ident;
     };
 
-    static const char *tochars[TOKMAX];
-
-    static Token *freelist;
-    static Token *alloc();
     void free();
 
     Token() : next(NULL) {}
     int isKeyword();
     const char *toChars() const;
-    static const char *toChars(TOK);
+
+    static const char *toChars(unsigned value);
 };
 
 #if defined(__GNUC__)
diff --git a/gcc/d/dmd/version.h b/gcc/d/dmd/version.h
index 33811eef762..6c5e2f0f236 100644
--- a/gcc/d/dmd/version.h
+++ b/gcc/d/dmd/version.h
@@ -5,7 +5,7 @@
  * http://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/dlang/dmd/blob/master/src/version.h
+ * https://github.com/dlang/dmd/blob/master/src/dmd/version.h
  */
 
 #pragma once
@@ -17,14 +17,12 @@ class DebugSymbol : public Dsymbol
 public:
     unsigned level;
 
-    DebugSymbol(Loc loc, Identifier *ident);
-    DebugSymbol(Loc loc, unsigned level);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    DebugSymbol *syntaxCopy(Dsymbol *);
 
-    const char *toChars();
+    const char *toChars() const;
     void addMember(Scope *sc, ScopeDsymbol *sds);
     const char *kind() const;
-    DebugSymbol *isDebugSymbol() { return this; }
+    DebugSymbol *isDebugSymbol();
     void accept(Visitor *v) { v->visit(this); }
 };
 
@@ -33,13 +31,11 @@ class VersionSymbol : public Dsymbol
 public:
     unsigned level;
 
-    VersionSymbol(Loc loc, Identifier *ident);
-    VersionSymbol(Loc loc, unsigned level);
-    Dsymbol *syntaxCopy(Dsymbol *);
+    VersionSymbol *syntaxCopy(Dsymbol *);
 
-    const char *toChars();
+    const char *toChars() const;
     void addMember(Scope *sc, ScopeDsymbol *sds);
     const char *kind() const;
-    VersionSymbol *isVersionSymbol() { return this; }
+    VersionSymbol *isVersionSymbol();
     void accept(Visitor *v) { v->visit(this); }
 };
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index 09ba2024e30..e61f16d7c8b 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -84,6 +84,7 @@ class TypeNull;
 class TypeNoreturn;
 class TypeTraits;
 class TypeMixin;
+class TypeTag;
 
 class Dsymbol;
 
@@ -101,7 +102,8 @@ class StorageClassDeclaration;
 class DeprecatedDeclaration;
 class LinkDeclaration;
 class CPPMangleDeclaration;
-class ProtDeclaration;
+class CPPNamespaceDeclaration;
+class VisibilityDeclaration;
 class AlignDeclaration;
 class AnonDeclaration;
 class PragmaDeclaration;
@@ -122,6 +124,7 @@ class Module;
 class WithScopeSymbol;
 class ArrayScopeSymbol;
 class Nspace;
+class AliasAssign;
 
 class AggregateDeclaration;
 class StructDeclaration;
@@ -136,6 +139,7 @@ class OverDeclaration;
 class VarDeclaration;
 class SymbolDeclaration;
 class ThisDeclaration;
+class BitFieldDeclaration;
 
 class TypeInfoDeclaration;
 class TypeInfoStructDeclaration;
@@ -168,7 +172,6 @@ class SharedStaticDtorDeclaration;
 class InvariantDeclaration;
 class UnitTestDeclaration;
 class NewDeclaration;
-class DeleteDeclaration;
 
 class Initializer;
 class VoidInitializer;
@@ -176,6 +179,7 @@ class ErrorInitializer;
 class StructInitializer;
 class ArrayInitializer;
 class ExpInitializer;
+class CInitializer;
 
 class Expression;
 class IntegerExp;
@@ -193,6 +197,8 @@ class TupleExp;
 class ArrayLiteralExp;
 class AssocArrayLiteralExp;
 class StructLiteralExp;
+class CompoundLiteralExp;
+class ObjcClassReferenceExp;
 class TypeExp;
 class ScopeExp;
 class TemplateExp;
@@ -211,7 +217,7 @@ class IsExp;
 class UnaExp;
 class BinExp;
 class BinAssignExp;
-class CompileExp;
+class MixinExp;
 class ImportExp;
 class AssertExp;
 class DotIdExp;
@@ -287,6 +293,7 @@ class PrettyFuncInitExp;
 class ClassReferenceExp;
 class VoidInitExp;
 class ThrownExceptionExp;
+class GenericExp;
 
 class TemplateParameter;
 class TemplateTypeParameter;
@@ -303,135 +310,301 @@ class StaticIfCondition;
 
 class Parameter;
 
-class Visitor
+class ParseTimeVisitor
 {
 public:
+    virtual void visit(Dsymbol *) { assert(0); }
+    virtual void visit(Parameter *) { assert(0); }
     virtual void visit(Statement *) { assert(0); }
-    virtual void visit(ErrorStatement *s) { visit((Statement *)s); }
-    virtual void visit(PeelStatement *s) { visit((Statement *)s); }
-    virtual void visit(ExpStatement *s) { visit((Statement *)s); }
-    virtual void visit(DtorExpStatement *s) { visit((ExpStatement *)s); }
-    virtual void visit(CompileStatement *s) { visit((Statement *)s); }
-    virtual void visit(CompoundStatement *s) { visit((Statement *)s); }
-    virtual void visit(CompoundDeclarationStatement *s) { visit((CompoundStatement *)s); }
-    virtual void visit(UnrolledLoopStatement *s) { visit((Statement *)s); }
+    virtual void visit(Type *) { assert(0); }
+    virtual void visit(Expression *) { assert(0); }
+    virtual void visit(TemplateParameter *) { assert(0); }
+    virtual void visit(Condition *) { assert(0); }
+    virtual void visit(Initializer *) { assert(0); }
+
+    // Dsymbols
+    virtual void visit(AliasThis *s) { visit((Dsymbol *)s); }
+    virtual void visit(Declaration *s) { visit((Dsymbol *)s); }
+    virtual void visit(ScopeDsymbol *s) { visit((Dsymbol *)s); }
+    virtual void visit(Import *s) { visit((Dsymbol *)s); }
+    virtual void visit(AttribDeclaration *s) { visit((Dsymbol *)s); }
+    virtual void visit(StaticAssert *s) { visit((Dsymbol *)s); }
+    virtual void visit(DebugSymbol *s) { visit((Dsymbol *)s); }
+    virtual void visit(VersionSymbol *s) { visit((Dsymbol *)s); }
+    virtual void visit(AliasAssign *s) { visit((Dsymbol *)s); }
+
+    // ScopeDsymbols
+    virtual void visit(Package *s) { visit((ScopeDsymbol *)s); }
+    virtual void visit(EnumDeclaration *s) { visit((ScopeDsymbol *)s); }
+    virtual void visit(AggregateDeclaration *s) { visit((ScopeDsymbol *)s); }
+    virtual void visit(TemplateDeclaration *s) { visit((ScopeDsymbol *)s); }
+    virtual void visit(TemplateInstance *s) { visit((ScopeDsymbol *)s); }
+    virtual void visit(Nspace *s) { visit((ScopeDsymbol *)s); }
+
+    // Declarations
+    virtual void visit(VarDeclaration *s) { visit((Declaration *)s); }
+    virtual void visit(FuncDeclaration *s) { visit((Declaration *)s); }
+    virtual void visit(AliasDeclaration *s) { visit((Declaration *)s); }
+    virtual void visit(TupleDeclaration *s) { visit((Declaration *)s); }
+
+    // FuncDeclarations
+    virtual void visit(FuncLiteralDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(PostBlitDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(CtorDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(DtorDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(InvariantDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(UnitTestDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(NewDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(StaticCtorDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(StaticDtorDeclaration *s) { visit((FuncDeclaration *)s); }
+    virtual void visit(SharedStaticCtorDeclaration *s) { visit((StaticCtorDeclaration *)s); }
+    virtual void visit(SharedStaticDtorDeclaration *s) { visit((StaticDtorDeclaration *)s); }
+
+    // AttribDeclarations
+    virtual void visit(CompileDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(UserAttributeDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(LinkDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(AnonDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(AlignDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(CPPMangleDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(CPPNamespaceDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(VisibilityDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(PragmaDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(StorageClassDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(ConditionalDeclaration *s) { visit((AttribDeclaration *)s); }
+    virtual void visit(StaticForeachDeclaration *s) { visit((AttribDeclaration *)s); }
+
+    // Miscellaneous
+    virtual void visit(DeprecatedDeclaration *s) { visit((StorageClassDeclaration *)s); }
+    virtual void visit(StaticIfDeclaration *s) { visit((ConditionalDeclaration *)s); }
+    virtual void visit(EnumMember *s) { visit((VarDeclaration *)s); }
+    virtual void visit(Module *s) { visit((Package *)s); }
+    virtual void visit(StructDeclaration *s) { visit((AggregateDeclaration *)s); }
+    virtual void visit(UnionDeclaration *s) { visit((StructDeclaration *)s); }
+    virtual void visit(ClassDeclaration *s) { visit((AggregateDeclaration *)s); }
+    virtual void visit(InterfaceDeclaration *s) { visit((ClassDeclaration *)s); }
+    virtual void visit(TemplateMixin *s) { visit((TemplateInstance *)s); }
+    virtual void visit(BitFieldDeclaration *s) { visit((VarDeclaration *)s); }
+
+    // Statements
+    virtual void visit(ImportStatement *s) { visit((Statement *)s); }
     virtual void visit(ScopeStatement *s) { visit((Statement *)s); }
-    virtual void visit(ForwardingStatement *s) { visit((Statement *)s); }
+    virtual void visit(ReturnStatement *s) { visit((Statement *)s); }
+    virtual void visit(LabelStatement *s) { visit((Statement *)s); }
+    virtual void visit(StaticAssertStatement *s) { visit((Statement *)s); }
+    virtual void visit(CompileStatement *s) { visit((Statement *)s); }
     virtual void visit(WhileStatement *s) { visit((Statement *)s); }
-    virtual void visit(DoStatement *s) { visit((Statement *)s); }
     virtual void visit(ForStatement *s) { visit((Statement *)s); }
-    virtual void visit(ForeachStatement *s) { visit((Statement *)s); }
+    virtual void visit(DoStatement *s) { visit((Statement *)s); }
     virtual void visit(ForeachRangeStatement *s) { visit((Statement *)s); }
-    virtual void visit(StaticForeachStatement *s) { visit((Statement *)s); }
+    virtual void visit(ForeachStatement *s) { visit((Statement *)s); }
     virtual void visit(IfStatement *s) { visit((Statement *)s); }
+    virtual void visit(ScopeGuardStatement *s) { visit((Statement *)s); }
     virtual void visit(ConditionalStatement *s) { visit((Statement *)s); }
+    virtual void visit(StaticForeachStatement *s) { visit((Statement *)s); }
     virtual void visit(PragmaStatement *s) { visit((Statement *)s); }
-    virtual void visit(StaticAssertStatement *s) { visit((Statement *)s); }
     virtual void visit(SwitchStatement *s) { visit((Statement *)s); }
-    virtual void visit(CaseStatement *s) { visit((Statement *)s); }
     virtual void visit(CaseRangeStatement *s) { visit((Statement *)s); }
+    virtual void visit(CaseStatement *s) { visit((Statement *)s); }
     virtual void visit(DefaultStatement *s) { visit((Statement *)s); }
-    virtual void visit(GotoDefaultStatement *s) { visit((Statement *)s); }
-    virtual void visit(GotoCaseStatement *s) { visit((Statement *)s); }
-    virtual void visit(SwitchErrorStatement *s) { visit((Statement *)s); }
-    virtual void visit(ReturnStatement *s) { visit((Statement *)s); }
     virtual void visit(BreakStatement *s) { visit((Statement *)s); }
     virtual void visit(ContinueStatement *s) { visit((Statement *)s); }
+    virtual void visit(GotoDefaultStatement *s) { visit((Statement *)s); }
+    virtual void visit(GotoCaseStatement *s) { visit((Statement *)s); }
+    virtual void visit(GotoStatement *s) { visit((Statement *)s); }
     virtual void visit(SynchronizedStatement *s) { visit((Statement *)s); }
     virtual void visit(WithStatement *s) { visit((Statement *)s); }
     virtual void visit(TryCatchStatement *s) { visit((Statement *)s); }
     virtual void visit(TryFinallyStatement *s) { visit((Statement *)s); }
-    virtual void visit(ScopeGuardStatement *s) { visit((Statement *)s); }
     virtual void visit(ThrowStatement *s) { visit((Statement *)s); }
-    virtual void visit(DebugStatement *s) { visit((Statement *)s); }
-    virtual void visit(GotoStatement *s) { visit((Statement *)s); }
-    virtual void visit(LabelStatement *s) { visit((Statement *)s); }
     virtual void visit(AsmStatement *s) { visit((Statement *)s); }
+    virtual void visit(ExpStatement *s) { visit((Statement *)s); }
+    virtual void visit(CompoundStatement *s) { visit((Statement *)s); }
+
+    // CompoundStatements
+    virtual void visit(CompoundDeclarationStatement *s) { visit((CompoundStatement *)s); }
+    virtual void visit(CompoundAsmStatement *s) { visit((CompoundStatement *)s); }
+
+    // AsmStatements
     virtual void visit(InlineAsmStatement *s) { visit((AsmStatement *)s); }
     virtual void visit(GccAsmStatement *s) { visit((AsmStatement *)s); }
-    virtual void visit(CompoundAsmStatement *s) { visit((CompoundStatement *)s); }
-    virtual void visit(ImportStatement *s) { visit((Statement *)s); }
 
-    virtual void visit(Type *) { assert(0); }
-    virtual void visit(TypeError *t) { visit((Type *)t); }
-    virtual void visit(TypeNext *t) { visit((Type *)t); }
+    // Types
     virtual void visit(TypeBasic *t) { visit((Type *)t); }
+    virtual void visit(TypeError *t) { visit((Type *)t); }
+    virtual void visit(TypeNull *t) { visit((Type *)t); }
+    virtual void visit(TypeNoreturn *t) { visit((Type *)t); }
     virtual void visit(TypeVector *t) { visit((Type *)t); }
+    virtual void visit(TypeEnum *t) { visit((Type *)t); }
+    virtual void visit(TypeTuple *t) { visit((Type *)t); }
+    virtual void visit(TypeClass *t) { visit((Type *)t); }
+    virtual void visit(TypeStruct *t) { visit((Type *)t); }
+    virtual void visit(TypeNext *t) { visit((Type *)t); }
+    virtual void visit(TypeQualified *t) { visit((Type *)t); }
+    virtual void visit(TypeTraits *t) { visit((Type *)t); }
+    virtual void visit(TypeMixin *t) { visit((Type *)t); }
+    virtual void visit(TypeTag *t) { visit((Type *)t); }
+
+    // TypeNext
+    virtual void visit(TypeReference *t) { visit((TypeNext *)t); }
+    virtual void visit(TypeSlice *t) { visit((TypeNext *)t); }
+    virtual void visit(TypeDelegate *t) { visit((TypeNext *)t); }
+    virtual void visit(TypePointer *t) { visit((TypeNext *)t); }
+    virtual void visit(TypeFunction *t) { visit((TypeNext *)t); }
     virtual void visit(TypeArray *t) { visit((TypeNext *)t); }
-    virtual void visit(TypeSArray *t) { visit((TypeArray *)t); }
+
+    // TypeArray
     virtual void visit(TypeDArray *t) { visit((TypeArray *)t); }
     virtual void visit(TypeAArray *t) { visit((TypeArray *)t); }
-    virtual void visit(TypePointer *t) { visit((TypeNext *)t); }
-    virtual void visit(TypeReference *t) { visit((TypeNext *)t); }
-    virtual void visit(TypeFunction *t) { visit((TypeNext *)t); }
-    virtual void visit(TypeDelegate *t) { visit((TypeNext *)t); }
-    virtual void visit(TypeQualified *t) { visit((Type *)t); }
+    virtual void visit(TypeSArray *t) { visit((TypeArray *)t); }
+
+    // TypeQualified
     virtual void visit(TypeIdentifier *t) { visit((TypeQualified *)t); }
-    virtual void visit(TypeInstance *t) { visit((TypeQualified *)t); }
-    virtual void visit(TypeTypeof *t) { visit((TypeQualified *)t); }
     virtual void visit(TypeReturn *t) { visit((TypeQualified *)t); }
-    virtual void visit(TypeStruct *t) { visit((Type *)t); }
-    virtual void visit(TypeEnum *t) { visit((Type *)t); }
-    virtual void visit(TypeClass *t) { visit((Type *)t); }
-    virtual void visit(TypeTuple *t) { visit((Type *)t); }
-    virtual void visit(TypeSlice *t) { visit((TypeNext *)t); }
-    virtual void visit(TypeNull *t) { visit((Type *)t); }
-    virtual void visit(TypeNoreturn *t) { visit((Type *)t); }
-    virtual void visit(TypeTraits *t) { visit((Type *)t); }
-    virtual void visit(TypeMixin *t) { visit((Type *)t); }
+    virtual void visit(TypeTypeof *t) { visit((TypeQualified *)t); }
+    virtual void visit(TypeInstance *t) { visit((TypeQualified *)t); }
 
-    virtual void visit(Dsymbol *) { assert(0); }
+    // Expressions
+    virtual void visit(DeclarationExp *e) { visit((Expression *)e); }
+    virtual void visit(IntegerExp *e) { visit((Expression *)e); }
+    virtual void visit(NewAnonClassExp *e) { visit((Expression *)e); }
+    virtual void visit(IsExp *e) { visit((Expression *)e); }
+    virtual void visit(RealExp *e) { visit((Expression *)e); }
+    virtual void visit(NullExp *e) { visit((Expression *)e); }
+    virtual void visit(TypeidExp *e) { visit((Expression *)e); }
+    virtual void visit(TraitsExp *e) { visit((Expression *)e); }
+    virtual void visit(StringExp *e) { visit((Expression *)e); }
+    virtual void visit(NewExp *e) { visit((Expression *)e); }
+    virtual void visit(AssocArrayLiteralExp *e) { visit((Expression *)e); }
+    virtual void visit(ArrayLiteralExp *e) { visit((Expression *)e); }
+    virtual void visit(MixinExp *e) { visit((Expression *)e); }
+    virtual void visit(FuncExp *e) { visit((Expression *)e); }
+    virtual void visit(IntervalExp *e) { visit((Expression *)e); }
+    virtual void visit(TypeExp *e) { visit((Expression *)e); }
+    virtual void visit(ScopeExp *e) { visit((Expression *)e); }
+    virtual void visit(IdentifierExp *e) { visit((Expression *)e); }
+    virtual void visit(UnaExp *e) { visit((Expression *)e); }
+    virtual void visit(DefaultInitExp *e) { visit((Expression *)e); }
+    virtual void visit(BinExp *e) { visit((Expression *)e); }
+    virtual void visit(DsymbolExp *e) { visit((Expression *)e); }
+    virtual void visit(TemplateExp *e) { visit((Expression *)e); }
+    virtual void visit(SymbolExp *e) { visit((Expression *)e); }
+    virtual void visit(TupleExp *e) { visit((Expression *)e); }
+    virtual void visit(ThisExp *e) { visit((Expression *)e); }
+    virtual void visit(GenericExp *e) { visit((Expression *)e); }
 
-    virtual void visit(StaticAssert *s) { visit((Dsymbol *)s); }
-    virtual void visit(DebugSymbol *s) { visit((Dsymbol *)s); }
-    virtual void visit(VersionSymbol *s) { visit((Dsymbol *)s); }
-    virtual void visit(EnumMember *s) { visit((VarDeclaration *)s); }
-    virtual void visit(Import *s) { visit((Dsymbol *)s); }
-    virtual void visit(OverloadSet *s) { visit((Dsymbol *)s); }
-    virtual void visit(LabelDsymbol *s) { visit((Dsymbol *)s); }
-    virtual void visit(AliasThis *s) { visit((Dsymbol *)s); }
+    // Miscellaneous
+    virtual void visit(VarExp *e) { visit((SymbolExp *)e); }
+    virtual void visit(DollarExp *e) { visit((IdentifierExp *)e); }
+    virtual void visit(SuperExp *e) { visit((ThisExp *)e); }
 
-    virtual void visit(AttribDeclaration *s) { visit((Dsymbol *)s); }
-    virtual void visit(StorageClassDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(DeprecatedDeclaration *s) { visit((StorageClassDeclaration *)s); }
-    virtual void visit(LinkDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(CPPMangleDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(ProtDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(AlignDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(AnonDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(PragmaDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(ConditionalDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(StaticIfDeclaration *s) { visit((ConditionalDeclaration *)s); }
-    virtual void visit(StaticForeachDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(CompileDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(UserAttributeDeclaration *s) { visit((AttribDeclaration *)s); }
-    virtual void visit(ForwardingAttribDeclaration *s) { visit((AttribDeclaration *)s); }
+    // UnaExp
+    virtual void visit(AddrExp *e) { visit((UnaExp *)e); }
+    virtual void visit(PreExp *e) { visit((UnaExp *)e); }
+    virtual void visit(PtrExp *e) { visit((UnaExp *)e); }
+    virtual void visit(NegExp *e) { visit((UnaExp *)e); }
+    virtual void visit(UAddExp *e) { visit((UnaExp *)e); }
+    virtual void visit(NotExp *e) { visit((UnaExp *)e); }
+    virtual void visit(ComExp *e) { visit((UnaExp *)e); }
+    virtual void visit(DeleteExp *e) { visit((UnaExp *)e); }
+    virtual void visit(CastExp *e) { visit((UnaExp *)e); }
+    virtual void visit(CallExp *e) { visit((UnaExp *)e); }
+    virtual void visit(DotIdExp *e) { visit((UnaExp *)e); }
+    virtual void visit(AssertExp *e) { visit((UnaExp *)e); }
+    virtual void visit(ImportExp *e) { visit((UnaExp *)e); }
+    virtual void visit(DotTemplateInstanceExp *e) { visit((UnaExp *)e); }
+    virtual void visit(ArrayExp *e) { visit((UnaExp *)e); }
 
-    virtual void visit(ScopeDsymbol *s) { visit((Dsymbol *)s); }
-    virtual void visit(TemplateDeclaration *s) { visit((ScopeDsymbol *)s); }
-    virtual void visit(TemplateInstance *s) { visit((ScopeDsymbol *)s); }
-    virtual void visit(TemplateMixin *s) { visit((TemplateInstance *)s); }
-    virtual void visit(EnumDeclaration *s) { visit((ScopeDsymbol *)s); }
-    virtual void visit(Package *s) { visit((ScopeDsymbol *)s); }
-    virtual void visit(Module *s) { visit((Package *)s); }
-    virtual void visit(WithScopeSymbol *s) { visit((ScopeDsymbol *)s); }
-    virtual void visit(ArrayScopeSymbol *s) { visit((ScopeDsymbol *)s); }
-    virtual void visit(Nspace *s) { visit((ScopeDsymbol *)s); }
+    // DefaultInitExp
+    virtual void visit(FuncInitExp *e) { visit((DefaultInitExp *)e); }
+    virtual void visit(PrettyFuncInitExp *e) { visit((DefaultInitExp *)e); }
+    virtual void visit(FileInitExp *e) { visit((DefaultInitExp *)e); }
+    virtual void visit(LineInitExp *e) { visit((DefaultInitExp *)e); }
+    virtual void visit(ModuleInitExp *e) { visit((DefaultInitExp *)e); }
 
-    virtual void visit(AggregateDeclaration *s) { visit((ScopeDsymbol *)s); }
-    virtual void visit(StructDeclaration *s) { visit((AggregateDeclaration *)s); }
-    virtual void visit(UnionDeclaration *s) { visit((StructDeclaration *)s); }
-    virtual void visit(ClassDeclaration *s) { visit((AggregateDeclaration *)s); }
-    virtual void visit(InterfaceDeclaration *s) { visit((ClassDeclaration *)s); }
+    // BinExp
+    virtual void visit(CommaExp *e) { visit((BinExp *)e); }
+    virtual void visit(PostExp *e) { visit((BinExp *)e); }
+    virtual void visit(PowExp *e) { visit((BinExp *)e); }
+    virtual void visit(MulExp *e) { visit((BinExp *)e); }
+    virtual void visit(DivExp *e) { visit((BinExp *)e); }
+    virtual void visit(ModExp *e) { visit((BinExp *)e); }
+    virtual void visit(AddExp *e) { visit((BinExp *)e); }
+    virtual void visit(MinExp *e) { visit((BinExp *)e); }
+    virtual void visit(CatExp *e) { visit((BinExp *)e); }
+    virtual void visit(ShlExp *e) { visit((BinExp *)e); }
+    virtual void visit(ShrExp *e) { visit((BinExp *)e); }
+    virtual void visit(UshrExp *e) { visit((BinExp *)e); }
+    virtual void visit(EqualExp *e) { visit((BinExp *)e); }
+    virtual void visit(InExp *e) { visit((BinExp *)e); }
+    virtual void visit(IdentityExp *e) { visit((BinExp *)e); }
+    virtual void visit(CmpExp *e) { visit((BinExp *)e); }
+    virtual void visit(AndExp *e) { visit((BinExp *)e); }
+    virtual void visit(XorExp *e) { visit((BinExp *)e); }
+    virtual void visit(OrExp *e) { visit((BinExp *)e); }
+    virtual void visit(LogicalExp *e) { visit((BinExp *)e); }
+    virtual void visit(CondExp *e) { visit((BinExp *)e); }
+    virtual void visit(AssignExp *e) { visit((BinExp *)e); }
+    virtual void visit(BinAssignExp *e) { visit((BinExp *)e); }
 
-    virtual void visit(Declaration *s) { visit((Dsymbol *)s); }
-    virtual void visit(TupleDeclaration *s) { visit((Declaration *)s); }
-    virtual void visit(AliasDeclaration *s) { visit((Declaration *)s); }
+    // BinAssignExp
+    virtual void visit(AddAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(MinAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(MulAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(DivAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(ModAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(PowAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(AndAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(OrAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(XorAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(ShlAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(ShrAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(UshrAssignExp *e) { visit((BinAssignExp *)e); }
+    virtual void visit(CatAssignExp *e) { visit((BinAssignExp *)e); }
+
+    // TemplateParameter
+    virtual void visit(TemplateAliasParameter *tp) { visit((TemplateParameter *)tp); }
+    virtual void visit(TemplateTypeParameter *tp) { visit((TemplateParameter *)tp); }
+    virtual void visit(TemplateTupleParameter *tp) { visit((TemplateParameter *)tp); }
+    virtual void visit(TemplateValueParameter *tp) { visit((TemplateParameter *)tp); }
+
+    virtual void visit(TemplateThisParameter *tp) { visit((TemplateTypeParameter *)tp); }
+
+    // Condition
+    virtual void visit(StaticIfCondition *c) { visit((Condition *)c); }
+    virtual void visit(DVCondition *c) { visit((Condition *)c); }
+    virtual void visit(DebugCondition *c) { visit((DVCondition *)c); }
+    virtual void visit(VersionCondition *c) { visit((DVCondition *)c); }
+
+    // Initializer
+    virtual void visit(ExpInitializer *i) { visit((Initializer *)i); }
+    virtual void visit(StructInitializer *i) { visit((Initializer *)i); }
+    virtual void visit(ArrayInitializer *i) { visit((Initializer *)i); }
+    virtual void visit(VoidInitializer *i) { visit((Initializer *)i); }
+    virtual void visit(CInitializer *i) { visit((Initializer *)i); }
+};
+
+class Visitor : public ParseTimeVisitor
+{
+public:
+    using ParseTimeVisitor::visit;
+
+    // Miscellaneous
+    virtual void visit(ErrorStatement *s) { visit((Statement *)s); }
+    virtual void visit(PeelStatement *s) { visit((Statement *)s); }
+    virtual void visit(UnrolledLoopStatement *s) { visit((Statement *)s); }
+    virtual void visit(SwitchErrorStatement *s) { visit((Statement *)s); }
+    virtual void visit(DebugStatement *s) { visit((Statement *)s); }
+    virtual void visit(DtorExpStatement *s) { visit((ExpStatement *)s); }
+    virtual void visit(ForwardingStatement *s) { visit((Statement *)s); }
+    virtual void visit(OverloadSet *s) { visit((Dsymbol *)s); }
+    virtual void visit(LabelDsymbol *s) { visit((Dsymbol *)s); }
+    virtual void visit(WithScopeSymbol *s) { visit((ScopeDsymbol *)s); }
+    virtual void visit(ArrayScopeSymbol *s) { visit((ScopeDsymbol *)s); }
     virtual void visit(OverDeclaration *s) { visit((Declaration *)s); }
-    virtual void visit(VarDeclaration *s) { visit((Declaration *)s); }
     virtual void visit(SymbolDeclaration *s) { visit((Declaration *)s); }
+    virtual void visit(ForwardingAttribDeclaration *s) { visit((AttribDeclaration *)s); }
     virtual void visit(ThisDeclaration *s) { visit((VarDeclaration *)s); }
-
     virtual void visit(TypeInfoDeclaration *s) { visit((VarDeclaration *)s); }
     virtual void visit(TypeInfoStructDeclaration *s) { visit((TypeInfoDeclaration *)s); }
     virtual void visit(TypeInfoClassDeclaration *s) { visit((TypeInfoDeclaration *)s); }
@@ -449,154 +622,34 @@ public:
     virtual void visit(TypeInfoSharedDeclaration *s) { visit((TypeInfoDeclaration *)s); }
     virtual void visit(TypeInfoWildDeclaration *s) { visit((TypeInfoDeclaration *)s); }
     virtual void visit(TypeInfoVectorDeclaration *s) { visit((TypeInfoDeclaration *)s); }
-
-    virtual void visit(FuncDeclaration *s) { visit((Declaration *)s); }
     virtual void visit(FuncAliasDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(FuncLiteralDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(CtorDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(PostBlitDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(DtorDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(StaticCtorDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(SharedStaticCtorDeclaration *s) { visit((StaticCtorDeclaration *)s); }
-    virtual void visit(StaticDtorDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(SharedStaticDtorDeclaration *s) { visit((StaticDtorDeclaration *)s); }
-    virtual void visit(InvariantDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(UnitTestDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(NewDeclaration *s) { visit((FuncDeclaration *)s); }
-    virtual void visit(DeleteDeclaration *s) { visit((FuncDeclaration *)s); }
-
-    virtual void visit(Initializer *) { assert(0); }
-    virtual void visit(VoidInitializer *i) { visit((Initializer *)i); }
     virtual void visit(ErrorInitializer *i) { visit((Initializer *)i); }
-    virtual void visit(StructInitializer *i) { visit((Initializer *)i); }
-    virtual void visit(ArrayInitializer *i) { visit((Initializer *)i); }
-    virtual void visit(ExpInitializer *i) { visit((Initializer *)i); }
-
-    virtual void visit(Expression *) { assert(0); }
-    virtual void visit(IntegerExp *e) { visit((Expression *)e); }
     virtual void visit(ErrorExp *e) { visit((Expression *)e); }
-    virtual void visit(RealExp *e) { visit((Expression *)e); }
     virtual void visit(ComplexExp *e) { visit((Expression *)e); }
-    virtual void visit(IdentifierExp *e) { visit((Expression *)e); }
-    virtual void visit(DollarExp *e) { visit((IdentifierExp *)e); }
-    virtual void visit(DsymbolExp *e) { visit((Expression *)e); }
-    virtual void visit(ThisExp *e) { visit((Expression *)e); }
-    virtual void visit(SuperExp *e) { visit((ThisExp *)e); }
-    virtual void visit(NullExp *e) { visit((Expression *)e); }
-    virtual void visit(StringExp *e) { visit((Expression *)e); }
-    virtual void visit(TupleExp *e) { visit((Expression *)e); }
-    virtual void visit(ArrayLiteralExp *e) { visit((Expression *)e); }
-    virtual void visit(AssocArrayLiteralExp *e) { visit((Expression *)e); }
     virtual void visit(StructLiteralExp *e) { visit((Expression *)e); }
-    virtual void visit(TypeExp *e) { visit((Expression *)e); }
-    virtual void visit(ScopeExp *e) { visit((Expression *)e); }
-    virtual void visit(TemplateExp *e) { visit((Expression *)e); }
-    virtual void visit(NewExp *e) { visit((Expression *)e); }
-    virtual void visit(NewAnonClassExp *e) { visit((Expression *)e); }
-    virtual void visit(SymbolExp *e) { visit((Expression *)e); }
+    virtual void visit(CompoundLiteralExp *e) { visit((Expression *)e); }
+    virtual void visit(ObjcClassReferenceExp *e) { visit((Expression *)e); }
     virtual void visit(SymOffExp *e) { visit((SymbolExp *)e); }
-    virtual void visit(VarExp *e) { visit((SymbolExp *)e); }
     virtual void visit(OverExp *e) { visit((Expression *)e); }
-    virtual void visit(FuncExp *e) { visit((Expression *)e); }
-    virtual void visit(DeclarationExp *e) { visit((Expression *)e); }
-    virtual void visit(TypeidExp *e) { visit((Expression *)e); }
-    virtual void visit(TraitsExp *e) { visit((Expression *)e); }
     virtual void visit(HaltExp *e) { visit((Expression *)e); }
-    virtual void visit(IsExp *e) { visit((Expression *)e); }
-    virtual void visit(UnaExp *e) { visit((Expression *)e); }
-    virtual void visit(BinExp *e) { visit((Expression *)e); }
-    virtual void visit(BinAssignExp *e) { visit((BinExp *)e); }
-    virtual void visit(CompileExp *e) { visit((UnaExp *)e); }
-    virtual void visit(ImportExp *e) { visit((UnaExp *)e); }
-    virtual void visit(AssertExp *e) { visit((UnaExp *)e); }
-    virtual void visit(DotIdExp *e) { visit((UnaExp *)e); }
     virtual void visit(DotTemplateExp *e) { visit((UnaExp *)e); }
     virtual void visit(DotVarExp *e) { visit((UnaExp *)e); }
-    virtual void visit(DotTemplateInstanceExp *e) { visit((UnaExp *)e); }
     virtual void visit(DelegateExp *e) { visit((UnaExp *)e); }
     virtual void visit(DotTypeExp *e) { visit((UnaExp *)e); }
-    virtual void visit(CallExp *e) { visit((UnaExp *)e); }
-    virtual void visit(AddrExp *e) { visit((UnaExp *)e); }
-    virtual void visit(PtrExp *e) { visit((UnaExp *)e); }
-    virtual void visit(NegExp *e) { visit((UnaExp *)e); }
-    virtual void visit(UAddExp *e) { visit((UnaExp *)e); }
-    virtual void visit(ComExp *e) { visit((UnaExp *)e); }
-    virtual void visit(NotExp *e) { visit((UnaExp *)e); }
-    virtual void visit(DeleteExp *e) { visit((UnaExp *)e); }
-    virtual void visit(CastExp *e) { visit((UnaExp *)e); }
     virtual void visit(VectorExp *e) { visit((UnaExp *)e); }
     virtual void visit(VectorArrayExp *e) { visit((UnaExp *)e); }
     virtual void visit(SliceExp *e) { visit((UnaExp *)e); }
     virtual void visit(ArrayLengthExp *e) { visit((UnaExp *)e); }
-    virtual void visit(IntervalExp *e) { visit((Expression *)e); }
     virtual void visit(DelegatePtrExp *e) { visit((UnaExp *)e); }
     virtual void visit(DelegateFuncptrExp *e) { visit((UnaExp *)e); }
-    virtual void visit(ArrayExp *e) { visit((UnaExp *)e); }
     virtual void visit(DotExp *e) { visit((BinExp *)e); }
-    virtual void visit(CommaExp *e) { visit((BinExp *)e); }
     virtual void visit(IndexExp *e) { visit((BinExp *)e); }
-    virtual void visit(PostExp *e) { visit((BinExp *)e); }
-    virtual void visit(PreExp *e) { visit((UnaExp *)e); }
-    virtual void visit(AssignExp *e) { visit((BinExp *)e); }
     virtual void visit(ConstructExp *e) { visit((AssignExp *)e); }
     virtual void visit(BlitExp *e) { visit((AssignExp *)e); }
-    virtual void visit(AddAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(MinAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(MulAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(DivAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(ModAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(AndAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(OrAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(XorAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(PowAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(ShlAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(ShrAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(UshrAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(CatAssignExp *e) { visit((BinAssignExp *)e); }
-    virtual void visit(AddExp *e) { visit((BinExp *)e); }
-    virtual void visit(MinExp *e) { visit((BinExp *)e); }
-    virtual void visit(CatExp *e) { visit((BinExp *)e); }
-    virtual void visit(MulExp *e) { visit((BinExp *)e); }
-    virtual void visit(DivExp *e) { visit((BinExp *)e); }
-    virtual void visit(ModExp *e) { visit((BinExp *)e); }
-    virtual void visit(PowExp *e) { visit((BinExp *)e); }
-    virtual void visit(ShlExp *e) { visit((BinExp *)e); }
-    virtual void visit(ShrExp *e) { visit((BinExp *)e); }
-    virtual void visit(UshrExp *e) { visit((BinExp *)e); }
-    virtual void visit(AndExp *e) { visit((BinExp *)e); }
-    virtual void visit(OrExp *e) { visit((BinExp *)e); }
-    virtual void visit(XorExp *e) { visit((BinExp *)e); }
-    virtual void visit(LogicalExp *e) { visit((BinExp *)e); }
-    virtual void visit(CmpExp *e) { visit((BinExp *)e); }
-    virtual void visit(InExp *e) { visit((BinExp *)e); }
     virtual void visit(RemoveExp *e) { visit((BinExp *)e); }
-    virtual void visit(EqualExp *e) { visit((BinExp *)e); }
-    virtual void visit(IdentityExp *e) { visit((BinExp *)e); }
-    virtual void visit(CondExp *e) { visit((BinExp *)e); }
-    virtual void visit(DefaultInitExp *e) { visit((Expression *)e); }
-    virtual void visit(FileInitExp *e) { visit((DefaultInitExp *)e); }
-    virtual void visit(LineInitExp *e) { visit((DefaultInitExp *)e); }
-    virtual void visit(ModuleInitExp *e) { visit((DefaultInitExp *)e); }
-    virtual void visit(FuncInitExp *e) { visit((DefaultInitExp *)e); }
-    virtual void visit(PrettyFuncInitExp *e) { visit((DefaultInitExp *)e); }
     virtual void visit(ClassReferenceExp *e) { visit((Expression *)e); }
     virtual void visit(VoidInitExp *e) { visit((Expression *)e); }
     virtual void visit(ThrownExceptionExp *e) { visit((Expression *)e); }
-
-    virtual void visit(TemplateParameter *) { assert(0); }
-    virtual void visit(TemplateTypeParameter *tp) { visit((TemplateParameter *)tp); }
-    virtual void visit(TemplateThisParameter *tp) { visit((TemplateTypeParameter *)tp); }
-    virtual void visit(TemplateValueParameter *tp) { visit((TemplateParameter *)tp); }
-    virtual void visit(TemplateAliasParameter *tp) { visit((TemplateParameter *)tp); }
-    virtual void visit(TemplateTupleParameter *tp) { visit((TemplateParameter *)tp); }
-
-    virtual void visit(Condition *) { assert(0); }
-    virtual void visit(DVCondition *c) { visit((Condition *)c); }
-    virtual void visit(DebugCondition *c) { visit((DVCondition *)c); }
-    virtual void visit(VersionCondition *c) { visit((DVCondition *)c); }
-    virtual void visit(StaticIfCondition *c) { visit((Condition *)c); }
-
-    virtual void visit(Parameter *) { assert(0); }
 };
 
 class StoppableVisitor : public Visitor
