diff mbox series

[committed] d: Merge upstream dmd 13d67c575.

Message ID 20200609170235.10454-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd 13d67c575. | expand

Commit Message

Iain Buclaw June 9, 2020, 5:02 p.m. UTC
Hi,

This patch merges the D front-end implementation with upstream dmd
13d67c575.  Contains many small API changes, most contained within the
front-end, but some spill out into the codegen.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain.


gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd 13d67c575.
	* d-builtins.cc (build_frontend_type): Update call to
	TypeVector::create.
	* d-frontend.cc (Global::_init): Move setting of errorLimit to ...
	* d-lang.cc (d_init_options): ... here.  Update for new field
	location of errorLimit.
	(d_post_options): Likewise.
	* d-port.cc (Port::readwordLE): Update signature.
	(Port::readwordBE): Likewise.
	(Port::readlongLE): Likewise.
	(Port::readlongBE): Likewise.
	* decl.cc (get_symbol_decl): Update for new field types.
---
 gcc/d/d-builtins.cc     |   2 +-
 gcc/d/d-frontend.cc     |   1 -
 gcc/d/d-lang.cc         |   3 +-
 gcc/d/d-port.cc         |  16 +-
 gcc/d/decl.cc           |   8 +-
 gcc/d/dmd/MERGE         |   2 +-
 gcc/d/dmd/access.c      |   2 +
 gcc/d/dmd/aggregate.h   |   1 +
 gcc/d/dmd/ast_node.h    |  20 ++
 gcc/d/dmd/cond.h        |   5 +-
 gcc/d/dmd/ctfeexpr.c    |   4 +-
 gcc/d/dmd/dclass.c      |  10 +-
 gcc/d/dmd/declaration.h |   2 +-
 gcc/d/dmd/dmangle.c     |   8 +-
 gcc/d/dmd/dsymbol.h     |   6 +-
 gcc/d/dmd/expression.c  | 518 ++++++++++++++++++++++++++++++++++++++++
 gcc/d/dmd/expression.h  | 109 ++++++++-
 gcc/d/dmd/globals.h     |   5 +-
 gcc/d/dmd/init.h        |   6 +-
 gcc/d/dmd/mtype.c       | 104 +++++++-
 gcc/d/dmd/mtype.h       |  32 ++-
 gcc/d/dmd/root/port.h   |   8 +-
 gcc/d/dmd/statement.h   |   5 +-
 gcc/d/dmd/template.h    |   4 +-
 gcc/d/dmd/utf.c         |  19 +-
 25 files changed, 843 insertions(+), 57 deletions(-)
 create mode 100644 gcc/d/dmd/ast_node.h
diff mbox series

Patch

diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 33221ea3229..91e3173e670 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -211,7 +211,7 @@  build_frontend_type (tree type)
       if (dtype->nextOf ()->isTypeBasic () == NULL)
 	break;
 
-      dtype = (TypeVector::create (Loc (), dtype))->addMod (mod);
+      dtype = (TypeVector::create (dtype))->addMod (mod);
       builtin_converted_decls.safe_push (builtin_data (dtype, type));
       return dtype;
     }
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index 90cf74a0f61..5415d471ef4 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -55,7 +55,6 @@  Global::_init (void)
     ;
 
   this->stdmsg = stderr;
-  this->errorLimit = flag_max_errors;
 }
 
 /* Start gagging. Return the current number of gagged errors.  */
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 2bc0def02c3..badd67f5a8f 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -293,6 +293,7 @@  d_init_options (unsigned int, cl_decoded_option *decoded_options)
   global.params.hdrStripPlainFunctions = true;
   global.params.betterC = false;
   global.params.allInst = false;
+  global.params.errorLimit = flag_max_errors;
 
   /* Default extern(C++) mangling to C++14.  */
   global.params.cplusplus = CppStdRevisionCpp14;
@@ -793,7 +794,7 @@  d_post_options (const char ** fn)
 
   /* Make -fmax-errors visible to frontend's diagnostic machinery.  */
   if (global_options_set.x_flag_max_errors)
-    global.errorLimit = flag_max_errors;
+    global.params.errorLimit = flag_max_errors;
 
   if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
     flag_excess_precision = EXCESS_PRECISION_STANDARD;
diff --git a/gcc/d/d-port.cc b/gcc/d/d-port.cc
index f129fd8843d..d49bb1ba8f3 100644
--- a/gcc/d/d-port.cc
+++ b/gcc/d/d-port.cc
@@ -97,9 +97,9 @@  Port::isFloat64LiteralOutOfRange (const char *buffer)
 /* Fetch a little-endian 16-bit value from BUFFER.  */
 
 unsigned
-Port::readwordLE (void *buffer)
+Port::readwordLE (const void *buffer)
 {
-  unsigned char *p = (unsigned char*) buffer;
+  const unsigned char *p = (const unsigned char*) buffer;
 
   return ((unsigned) p[1] << 8) | (unsigned) p[0];
 }
@@ -107,9 +107,9 @@  Port::readwordLE (void *buffer)
 /* Fetch a big-endian 16-bit value from BUFFER.  */
 
 unsigned
-Port::readwordBE (void *buffer)
+Port::readwordBE (const void *buffer)
 {
-  unsigned char *p = (unsigned char*) buffer;
+  const unsigned char *p = (const unsigned char*) buffer;
 
   return ((unsigned) p[0] << 8) | (unsigned) p[1];
 }
@@ -117,9 +117,9 @@  Port::readwordBE (void *buffer)
 /* Fetch a little-endian 32-bit value from BUFFER.  */
 
 unsigned
-Port::readlongLE (void *buffer)
+Port::readlongLE (const void *buffer)
 {
-  unsigned char *p = (unsigned char*) buffer;
+  const unsigned char *p = (const unsigned char*) buffer;
 
   return (((unsigned) p[3] << 24)
 	  | ((unsigned) p[2] << 16)
@@ -130,9 +130,9 @@  Port::readlongLE (void *buffer)
 /* Fetch a big-endian 32-bit value from BUFFER.  */
 
 unsigned
-Port::readlongBE (void *buffer)
+Port::readlongBE (const void *buffer)
 {
-  unsigned char *p = (unsigned char*) buffer;
+  const unsigned char *p = (const unsigned char*) buffer;
 
   return (((unsigned) p[0] << 24)
 	  | ((unsigned) p[1] << 16)
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index bcee0b21e7d..84aa42c139b 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1134,8 +1134,12 @@  get_symbol_decl (Declaration *decl)
     {
       tree mangled_name;
 
-      if (decl->mangleOverride)
-	mangled_name = get_identifier (decl->mangleOverride);
+      if (decl->mangleOverride.length)
+	{
+	  mangled_name =
+	    get_identifier_with_length (decl->mangleOverride.ptr,
+					decl->mangleOverride.length);
+	}
       else
 	mangled_name = get_identifier (d_mangle_decl (decl));
 
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 163a70ddb26..d6b2a2a3791 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-5041e56f12806f13a8fa5e98a6c98279636a8d2a
+13d67c5757b83a86411e510bd65a6b5167241324
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/access.c b/gcc/d/dmd/access.c
index f79eaeb8690..1a7238a31cc 100644
--- a/gcc/d/dmd/access.c
+++ b/gcc/d/dmd/access.c
@@ -434,6 +434,7 @@  bool symbolIsVisible(Module *mod, Dsymbol *s)
         default:
             assert(0);
     }
+    return false;
 }
 
 /**
@@ -475,6 +476,7 @@  bool symbolIsVisible(Scope *sc, Dsymbol *s)
         default:
             assert(0);
     }
+    return false;
 }
 
 /**
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index c20df57cb04..6cfc76d8c6c 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -310,6 +310,7 @@  public:
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
     ClassDeclaration *searchBase(Identifier *ident);
     void finalizeSize();
+    bool hasMonitor();
     bool isFuncHidden(FuncDeclaration *fd);
     FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
     void interfaceSemantic(Scope *sc);
diff --git a/gcc/d/dmd/ast_node.h b/gcc/d/dmd/ast_node.h
new file mode 100644
index 00000000000..09519af0e99
--- /dev/null
+++ b/gcc/d/dmd/ast_node.h
@@ -0,0 +1,20 @@ 
+
+/* Compiler implementation of the D programming language
+ * Copyright (C) 1999-2020 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/ast_node.h
+ */
+
+#pragma once
+
+#include "root/object.h"
+
+class Visitor;
+
+class ASTNode : public RootObject
+{
+    virtual void accept(Visitor*) = 0;
+};
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index 1963f0519a9..17398c1ef78 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -10,6 +10,7 @@ 
 
 #pragma once
 
+#include "ast_node.h"
 #include "globals.h"
 #include "visitor.h"
 
@@ -25,7 +26,7 @@  class ForeachRangeStatement;
 
 int findCondition(Identifiers *ids, Identifier *ident);
 
-class Condition
+class Condition : public ASTNode
 {
 public:
     Loc loc;
@@ -40,7 +41,7 @@  public:
     virtual int include(Scope *sc) = 0;
     virtual DebugCondition *isDebugCondition() { return NULL; }
     virtual VersionCondition *isVersionCondition() { return NULL; }
-    virtual void accept(Visitor *v) { v->visit(this); }
+    void accept(Visitor *v) { v->visit(this); }
 };
 
 class StaticForeach
diff --git a/gcc/d/dmd/ctfeexpr.c b/gcc/d/dmd/ctfeexpr.c
index 16ffede4882..5230647e626 100644
--- a/gcc/d/dmd/ctfeexpr.c
+++ b/gcc/d/dmd/ctfeexpr.c
@@ -1057,6 +1057,7 @@  static bool numCmp(TOK op, N n1, N n2)
         default:
             assert(0);
     }
+    return false;
 }
 
 /// Returns cmp OP 0; where OP is ==, !=, <, >=, etc. Result is 0 or 1
@@ -1089,11 +1090,12 @@  int realCmp(TOK op, real_t r1, real_t r2)
             case TOKle:
             case TOKgt:
             case TOKge:
-                return 0;
+                break;
 
             default:
                 assert(0);
         }
+        return 0;
     }
     else
     {
diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c
index 73e571b4da9..7481f910e11 100644
--- a/gcc/d/dmd/dclass.c
+++ b/gcc/d/dmd/dclass.c
@@ -1100,7 +1100,7 @@  void ClassDeclaration::finalizeSize()
     {
         alignsize = target.ptrsize;
         structsize = target.ptrsize;      // allow room for __vptr
-        if (!isCPPclass())
+        if (hasMonitor())
             structsize += target.ptrsize; // allow room for __monitor
     }
 
@@ -1133,6 +1133,14 @@  void ClassDeclaration::finalizeSize()
     checkOverlappedFields();
 }
 
+/**************
+ * Returns: true if there's a __monitor field
+ */
+bool ClassDeclaration::hasMonitor()
+{
+    return classKind == ClassKind::d;
+}
+
 /**********************************************************
  * fd is in the vtbl[] for this class.
  * Return 1 if function is hidden (not findable through search).
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index e74106391dc..251c407bf8c 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -123,7 +123,7 @@  public:
     Prot protection;
     LINK linkage;
     int inuse;                  // used to detect cycles
-    const char *mangleOverride;      // overridden symbol with pragma(mangle, "...")
+    DString mangleOverride;     // overridden symbol with pragma(mangle, "...")
 
     Declaration(Identifier *id);
     void semantic(Scope *sc);
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index 1c564b70e68..daa0e8c3bdc 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -520,9 +520,9 @@  public:
     {
         assert(!fd->isFuncAliasDeclaration());
 
-        if (fd->mangleOverride)
+        if (fd->mangleOverride.length)
         {
-            buf->writestring(fd->mangleOverride);
+            buf->writestring(fd->mangleOverride.ptr);
             return;
         }
 
@@ -543,9 +543,9 @@  public:
 
     void visit(VarDeclaration *vd)
     {
-        if (vd->mangleOverride)
+        if (vd->mangleOverride.length)
         {
-            buf->writestring(vd->mangleOverride);
+            buf->writestring(vd->mangleOverride.ptr);
             return;
         }
 
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 63dbc2cccbc..6e37f9bd1af 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -12,7 +12,7 @@ 
 
 #include "root/root.h"
 #include "root/stringtable.h"
-
+#include "ast_node.h"
 #include "globals.h"
 #include "arraytypes.h"
 #include "visitor.h"
@@ -145,7 +145,7 @@  enum
 
 typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *);
 
-class Dsymbol : public RootObject
+class Dsymbol : public ASTNode
 {
 public:
     Identifier *ident;
@@ -281,7 +281,7 @@  public:
     virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
     virtual AnonDeclaration *isAnonDeclaration() { return NULL; }
     virtual OverloadSet *isOverloadSet() { return NULL; }
-    virtual void accept(Visitor *v) { v->visit(this); }
+    void accept(Visitor *v) { v->visit(this); }
 };
 
 // Dsymbol that generates a scope
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index 0b21fc949c5..baa6f5f5a0d 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -2818,6 +2818,524 @@  bool Expression::isBool(bool)
     return false;
 }
 
+IntegerExp *Expression::isIntegerExp()
+{
+    return op == TOKint64 ? (IntegerExp *)this : NULL;
+}
+
+ErrorExp *Expression::isErrorExp()
+{
+    return op == TOKerror ? (ErrorExp *)this : NULL;
+}
+
+VoidInitExp *Expression::isVoidInitExp()
+{
+    return op == TOKvoid ? (VoidInitExp *)this : NULL;
+}
+
+RealExp *Expression::isRealExp()
+{
+    return op == TOKfloat64 ? (RealExp *)this : NULL;
+}
+
+ComplexExp *Expression::isComplexExp()
+{
+    return op == TOKcomplex80 ? (ComplexExp *)this : NULL;
+}
+
+IdentifierExp *Expression::isIdentifierExp()
+{
+    return op == TOKidentifier ? (IdentifierExp *)this : NULL;
+}
+
+DollarExp *Expression::isDollarExp()
+{
+    return op == TOKdollar ? (DollarExp *)this : NULL;
+}
+
+DsymbolExp *Expression::isDsymbolExp()
+{
+    return op == TOKdsymbol ? (DsymbolExp *)this : NULL;
+}
+
+ThisExp *Expression::isThisExp()
+{
+    return op == TOKthis ? (ThisExp *)this : NULL;
+}
+
+SuperExp *Expression::isSuperExp()
+{
+    return op == TOKsuper ? (SuperExp *)this : NULL;
+}
+
+NullExp *Expression::isNullExp()
+{
+    return op == TOKnull ? (NullExp *)this : NULL;
+}
+
+StringExp *Expression::isStringExp()
+{
+    return op == TOKstring ? (StringExp *)this : NULL;
+}
+
+TupleExp *Expression::isTupleExp()
+{
+    return op == TOKtuple ? (TupleExp *)this : NULL;
+}
+
+ArrayLiteralExp *Expression::isArrayLiteralExp()
+{
+    return op == TOKarrayliteral ? (ArrayLiteralExp *)this : NULL;
+}
+
+AssocArrayLiteralExp *Expression::isAssocArrayLiteralExp()
+{
+    return op == TOKassocarrayliteral ? (AssocArrayLiteralExp *)this : NULL;
+}
+
+StructLiteralExp *Expression::isStructLiteralExp()
+{
+    return op == TOKstructliteral ? (StructLiteralExp *)this : NULL;
+}
+
+TypeExp *Expression::isTypeExp()
+{
+    return op == TOKtype ? (TypeExp *)this : NULL;
+}
+
+ScopeExp *Expression::isScopeExp()
+{
+    return op == TOKscope ? (ScopeExp *)this : NULL;
+}
+
+TemplateExp *Expression::isTemplateExp()
+{
+    return op == TOKtemplate ? (TemplateExp *)this : NULL;
+}
+
+NewExp *Expression::isNewExp()
+{
+    return op == TOKnew ? (NewExp *)this : NULL;
+}
+
+NewAnonClassExp *Expression::isNewAnonClassExp()
+{
+    return op == TOKnewanonclass ? (NewAnonClassExp *)this : NULL;
+}
+
+SymOffExp *Expression::isSymOffExp()
+{
+    return op == TOKsymoff ? (SymOffExp *)this : NULL;
+}
+
+VarExp *Expression::isVarExp()
+{
+    return op == TOKvar ? (VarExp *)this : NULL;
+}
+
+OverExp *Expression::isOverExp()
+{
+    return op == TOKoverloadset ? (OverExp *)this : NULL;
+}
+
+FuncExp *Expression::isFuncExp()
+{
+    return op == TOKfunction ? (FuncExp *)this : NULL;
+}
+
+DeclarationExp *Expression::isDeclarationExp()
+{
+    return op == TOKdeclaration ? (DeclarationExp *)this : NULL;
+}
+
+TypeidExp *Expression::isTypeidExp()
+{
+    return op == TOKtypeid ? (TypeidExp *)this : NULL;
+}
+
+TraitsExp *Expression::isTraitsExp()
+{
+    return op == TOKtraits ? (TraitsExp *)this : NULL;
+}
+
+HaltExp *Expression::isHaltExp()
+{
+    return op == TOKhalt ? (HaltExp *)this : NULL;
+}
+
+IsExp *Expression::isExp()
+{
+    return op == TOKis ? (IsExp *)this : NULL;
+}
+
+CompileExp *Expression::isCompileExp()
+{
+    return op == TOKmixin ? (CompileExp *)this : NULL;
+}
+
+ImportExp *Expression::isImportExp()
+{
+    return op == TOKimport ? (ImportExp *)this : NULL;
+}
+
+AssertExp *Expression::isAssertExp()
+{
+    return op == TOKassert ? (AssertExp *)this : NULL;
+}
+
+DotIdExp *Expression::isDotIdExp()
+{
+    return op == TOKdotid ? (DotIdExp *)this : NULL;
+}
+
+DotTemplateExp *Expression::isDotTemplateExp()
+{
+    return op == TOKdotti ? (DotTemplateExp *)this : NULL;
+}
+
+DotVarExp *Expression::isDotVarExp()
+{
+    return op == TOKdotvar ? (DotVarExp *)this : NULL;
+}
+
+DotTemplateInstanceExp *Expression::isDotTemplateInstanceExp()
+{
+    return op == TOKdotti ? (DotTemplateInstanceExp *)this : NULL;
+}
+
+DelegateExp *Expression::isDelegateExp()
+{
+    return op == TOKdelegate ? (DelegateExp *)this : NULL;
+}
+
+DotTypeExp *Expression::isDotTypeExp()
+{
+    return op == TOKdottype ? (DotTypeExp *)this : NULL;
+}
+
+CallExp *Expression::isCallExp()
+{
+    return op == TOKcall ? (CallExp *)this : NULL;
+}
+
+AddrExp *Expression::isAddrExp()
+{
+    return op == TOKaddress ? (AddrExp *)this : NULL;
+}
+
+PtrExp *Expression::isPtrExp()
+{
+    return op == TOKstar ? (PtrExp *)this : NULL;
+}
+
+NegExp *Expression::isNegExp()
+{
+    return op == TOKneg ? (NegExp *)this : NULL;
+}
+
+UAddExp *Expression::isUAddExp()
+{
+    return op == TOKuadd ? (UAddExp *)this : NULL;
+}
+
+ComExp *Expression::isComExp()
+{
+    return op == TOKtilde ? (ComExp *)this : NULL;
+}
+
+NotExp *Expression::isNotExp()
+{
+    return op == TOKnot ? (NotExp *)this : NULL;
+}
+
+DeleteExp *Expression::isDeleteExp()
+{
+    return op == TOKdelete ? (DeleteExp *)this : NULL;
+}
+
+CastExp *Expression::isCastExp()
+{
+    return op == TOKcast ? (CastExp *)this : NULL;
+}
+
+VectorExp *Expression::isVectorExp()
+{
+    return op == TOKvector ? (VectorExp *)this : NULL;
+}
+
+VectorArrayExp *Expression::isVectorArrayExp()
+{
+    return op == TOKvectorarray ? (VectorArrayExp *)this : NULL;
+}
+
+SliceExp *Expression::isSliceExp()
+{
+    return op == TOKslice ? (SliceExp *)this : NULL;
+}
+
+ArrayLengthExp *Expression::isArrayLengthExp()
+{
+    return op == TOKarraylength ? (ArrayLengthExp *)this : NULL;
+}
+
+ArrayExp *Expression::isArrayExp()
+{
+    return op == TOKarray ? (ArrayExp *)this : NULL;
+}
+
+DotExp *Expression::isDotExp()
+{
+    return op == TOKdot ? (DotExp *)this : NULL;
+}
+
+CommaExp *Expression::isCommaExp()
+{
+    return op == TOKcomma ? (CommaExp *)this : NULL;
+}
+
+IntervalExp *Expression::isIntervalExp()
+{
+    return op == TOKinterval ? (IntervalExp *)this : NULL;
+}
+
+DelegatePtrExp *Expression::isDelegatePtrExp()
+{
+    return op == TOKdelegateptr ? (DelegatePtrExp *)this : NULL;
+}
+
+DelegateFuncptrExp *Expression::isDelegateFuncptrExp()
+{
+    return op == TOKdelegatefuncptr ? (DelegateFuncptrExp *)this : NULL;
+}
+
+IndexExp *Expression::isIndexExp()
+{
+    return op == TOKindex ? (IndexExp *)this : NULL;
+}
+
+PostExp *Expression::isPostExp()
+{
+    return (op == TOKplusplus || op == TOKminusminus) ? (PostExp *)this : NULL;
+}
+
+PreExp *Expression::isPreExp()
+{
+    return (op == TOKpreplusplus || op == TOKpreminusminus) ? (PreExp *)this : NULL;
+}
+
+AssignExp *Expression::isAssignExp()
+{
+    return op == TOKassign ? (AssignExp *)this : NULL;
+}
+
+ConstructExp *Expression::isConstructExp()
+{
+    return op == TOKconstruct ? (ConstructExp *)this : NULL;
+}
+
+BlitExp *Expression::isBlitExp()
+{
+    return op == TOKblit ? (BlitExp *)this : NULL;
+}
+
+AddAssignExp *Expression::isAddAssignExp()
+{
+    return op == TOKaddass ? (AddAssignExp *)this : NULL;
+}
+
+MinAssignExp *Expression::isMinAssignExp()
+{
+    return op == TOKminass ? (MinAssignExp *)this : NULL;
+}
+
+MulAssignExp *Expression::isMulAssignExp()
+{
+    return op == TOKmulass ? (MulAssignExp *)this : NULL;
+}
+
+
+DivAssignExp *Expression::isDivAssignExp()
+{
+    return op == TOKdivass ? (DivAssignExp *)this : NULL;
+}
+
+ModAssignExp *Expression::isModAssignExp()
+{
+    return op == TOKmodass ? (ModAssignExp *)this : NULL;
+}
+
+AndAssignExp *Expression::isAndAssignExp()
+{
+    return op == TOKandass ? (AndAssignExp *)this : NULL;
+}
+
+OrAssignExp *Expression::isOrAssignExp()
+{
+    return op == TOKorass ? (OrAssignExp *)this : NULL;
+}
+
+XorAssignExp *Expression::isXorAssignExp()
+{
+    return op == TOKxorass ? (XorAssignExp *)this : NULL;
+}
+
+PowAssignExp *Expression::isPowAssignExp()
+{
+    return op == TOKpowass ? (PowAssignExp *)this : NULL;
+}
+
+
+ShlAssignExp *Expression::isShlAssignExp()
+{
+    return op == TOKshlass ? (ShlAssignExp *)this : NULL;
+}
+
+ShrAssignExp *Expression::isShrAssignExp()
+{
+    return op == TOKshrass ? (ShrAssignExp *)this : NULL;
+}
+
+UshrAssignExp *Expression::isUshrAssignExp()
+{
+    return op == TOKushrass ? (UshrAssignExp *)this : NULL;
+}
+
+CatAssignExp *Expression::isCatAssignExp()
+{
+    return op == TOKcatass ? (CatAssignExp *)this : NULL;
+}
+
+AddExp *Expression::isAddExp()
+{
+    return op == TOKadd ? (AddExp *)this : NULL;
+}
+
+MinExp *Expression::isMinExp()
+{
+    return op == TOKmin ? (MinExp *)this : NULL;
+}
+
+CatExp *Expression::isCatExp()
+{
+    return op == TOKcat ? (CatExp *)this : NULL;
+}
+
+MulExp *Expression::isMulExp()
+{
+    return op == TOKmul ? (MulExp *)this : NULL;
+}
+
+DivExp *Expression::isDivExp()
+{
+    return op == TOKdiv ? (DivExp *)this : NULL;
+}
+
+ModExp *Expression::isModExp()
+{
+    return op == TOKmod ? (ModExp *)this : NULL;
+}
+
+PowExp *Expression::isPowExp()
+{
+    return op == TOKpow ? (PowExp *)this : NULL;
+}
+
+ShlExp *Expression::isShlExp()
+{
+    return op == TOKshl ? (ShlExp *)this : NULL;
+}
+
+ShrExp *Expression::isShrExp()
+{
+    return op == TOKshr ? (ShrExp *)this : NULL;
+}
+
+UshrExp *Expression::isUshrExp()
+{
+    return op == TOKushr ? (UshrExp *)this : NULL;
+}
+
+AndExp *Expression::isAndExp()
+{
+    return op == TOKand ? (AndExp *)this : NULL;
+}
+
+OrExp *Expression::isOrExp()
+{
+    return op == TOKor ? (OrExp *)this : NULL;
+}
+
+XorExp *Expression::isXorExp()
+{
+    return op == TOKxor ? (XorExp *)this : NULL;
+}
+
+LogicalExp *Expression::isLogicalExp()
+{
+    return (op == TOKandand || op == TOKoror) ? (LogicalExp *)this : NULL;
+}
+
+InExp *Expression::isInExp()
+{
+    return op == TOKin ? (InExp *)this : NULL;
+}
+
+RemoveExp *Expression::isRemoveExp()
+{
+    return op == TOKremove ? (RemoveExp *)this : NULL;
+}
+
+EqualExp *Expression::isEqualExp()
+{
+    return (op == TOKequal || op == TOKnotequal) ? (EqualExp *)this : NULL;
+}
+
+IdentityExp *Expression::isIdentityExp()
+{
+    return (op == TOKidentity || op == TOKnotidentity) ? (IdentityExp *)this : NULL;
+}
+
+CondExp *Expression::isCondExp()
+{
+    return op == TOKquestion ? (CondExp *)this : NULL;
+}
+
+DefaultInitExp *Expression::isDefaultInitExp()
+{
+    return op == TOKdefault ? (DefaultInitExp *)this : NULL;
+}
+
+FileInitExp *Expression::isFileInitExp()
+{
+    return (op == TOKfile || op == TOKfilefullpath) ? (FileInitExp *)this : NULL;
+}
+
+LineInitExp *Expression::isLineInitExp()
+{
+    return op == TOKline ? (LineInitExp *)this : NULL;
+}
+
+ModuleInitExp *Expression::isModuleInitExp()
+{
+    return op == TOKmodulestring ? (ModuleInitExp *)this : NULL;
+}
+
+FuncInitExp *Expression::isFuncInitExp()
+{
+    return op == TOKfuncstring ? (FuncInitExp *)this : NULL;
+}
+
+PrettyFuncInitExp *Expression::isPrettyFuncInitExp()
+{
+    return op == TOKprettyfunc ? (PrettyFuncInitExp *)this : NULL;
+}
+
+ClassReferenceExp *Expression::isClassReferenceExp()
+{
+    return op == TOKclassreference ? (ClassReferenceExp *)this : NULL;
+}
+
+
 /****************************************
  * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__ to loc.
  */
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index e353fdc96a5..fde029ce146 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -10,6 +10,7 @@ 
 
 #pragma once
 
+#include "ast_node.h"
 #include "complex_t.h"
 #include "globals.h"
 #include "identifier.h"
@@ -121,7 +122,7 @@  enum OwnedBy
 #define WANTvalue   0   // default
 #define WANTexpand  1   // expand const/immutable variables if possible
 
-class Expression : public RootObject
+class Expression : public ASTNode
 {
 public:
     Loc loc;                    // file location
@@ -218,7 +219,111 @@  public:
         return true;
     }
 
-    virtual void accept(Visitor *v) { v->visit(this); }
+    IntegerExp* isIntegerExp();
+    ErrorExp* isErrorExp();
+    VoidInitExp* isVoidInitExp();
+    RealExp* isRealExp();
+    ComplexExp* isComplexExp();
+    IdentifierExp* isIdentifierExp();
+    DollarExp* isDollarExp();
+    DsymbolExp* isDsymbolExp();
+    ThisExp* isThisExp();
+    SuperExp* isSuperExp();
+    NullExp* isNullExp();
+    StringExp* isStringExp();
+    TupleExp* isTupleExp();
+    ArrayLiteralExp* isArrayLiteralExp();
+    AssocArrayLiteralExp* isAssocArrayLiteralExp();
+    StructLiteralExp* isStructLiteralExp();
+    TypeExp* isTypeExp();
+    ScopeExp* isScopeExp();
+    TemplateExp* isTemplateExp();
+    NewExp* isNewExp();
+    NewAnonClassExp* isNewAnonClassExp();
+    SymOffExp* isSymOffExp();
+    VarExp* isVarExp();
+    OverExp* isOverExp();
+    FuncExp* isFuncExp();
+    DeclarationExp* isDeclarationExp();
+    TypeidExp* isTypeidExp();
+    TraitsExp* isTraitsExp();
+    HaltExp* isHaltExp();
+    IsExp* isExp();
+    CompileExp* isCompileExp();
+    ImportExp* isImportExp();
+    AssertExp* isAssertExp();
+    DotIdExp* isDotIdExp();
+    DotTemplateExp* isDotTemplateExp();
+    DotVarExp* isDotVarExp();
+    DotTemplateInstanceExp* isDotTemplateInstanceExp();
+    DelegateExp* isDelegateExp();
+    DotTypeExp* isDotTypeExp();
+    CallExp* isCallExp();
+    AddrExp* isAddrExp();
+    PtrExp* isPtrExp();
+    NegExp* isNegExp();
+    UAddExp* isUAddExp();
+    ComExp* isComExp();
+    NotExp* isNotExp();
+    DeleteExp* isDeleteExp();
+    CastExp* isCastExp();
+    VectorExp* isVectorExp();
+    VectorArrayExp* isVectorArrayExp();
+    SliceExp* isSliceExp();
+    ArrayLengthExp* isArrayLengthExp();
+    ArrayExp* isArrayExp();
+    DotExp* isDotExp();
+    CommaExp* isCommaExp();
+    IntervalExp* isIntervalExp();
+    DelegatePtrExp* isDelegatePtrExp();
+    DelegateFuncptrExp* isDelegateFuncptrExp();
+    IndexExp* isIndexExp();
+    PostExp* isPostExp();
+    PreExp* isPreExp();
+    AssignExp* isAssignExp();
+    ConstructExp* isConstructExp();
+    BlitExp* isBlitExp();
+    AddAssignExp* isAddAssignExp();
+    MinAssignExp* isMinAssignExp();
+    MulAssignExp* isMulAssignExp();
+    DivAssignExp* isDivAssignExp();
+    ModAssignExp* isModAssignExp();
+    AndAssignExp* isAndAssignExp();
+    OrAssignExp* isOrAssignExp();
+    XorAssignExp* isXorAssignExp();
+    PowAssignExp* isPowAssignExp();
+    ShlAssignExp* isShlAssignExp();
+    ShrAssignExp* isShrAssignExp();
+    UshrAssignExp* isUshrAssignExp();
+    CatAssignExp* isCatAssignExp();
+    AddExp* isAddExp();
+    MinExp* isMinExp();
+    CatExp* isCatExp();
+    MulExp* isMulExp();
+    DivExp* isDivExp();
+    ModExp* isModExp();
+    PowExp* isPowExp();
+    ShlExp* isShlExp();
+    ShrExp* isShrExp();
+    UshrExp* isUshrExp();
+    AndExp* isAndExp();
+    OrExp* isOrExp();
+    XorExp* isXorExp();
+    LogicalExp* isLogicalExp();
+    InExp* isInExp();
+    RemoveExp* isRemoveExp();
+    EqualExp* isEqualExp();
+    IdentityExp* isIdentityExp();
+    CondExp* isCondExp();
+    DefaultInitExp* isDefaultInitExp();
+    FileInitExp* isFileInitExp();
+    LineInitExp* isLineInitExp();
+    ModuleInitExp* isModuleInitExp();
+    FuncInitExp* isFuncInitExp();
+    PrettyFuncInitExp* isPrettyFuncInitExp();
+    ClassReferenceExp* isClassReferenceExp();
+
+    void accept(Visitor *v) { v->visit(this); }
 };
 
 class IntegerExp : public Expression
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 8a2ffdc2a56..9e1a5b2d15a 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -144,6 +144,8 @@  struct Param
 
     CHECKACTION checkAction;       // action to take when bounds, asserts or switch defaults are violated
 
+    unsigned errorLimit;
+
     DString  argv0;    // program name
     Array<const char *> modFileAliasStrings; // array of char*'s of -I module filename alias strings
     Array<const char *> *imppath;     // array of char*'s of where to look for import modules
@@ -235,8 +237,7 @@  struct Global
     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 errorLimit;
+    unsigned gaggedWarnings; // number of warnings reported while gagged
 
     void* console;         // opaque pointer to console for controlling text attributes
 
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 759734e92fb..6f98fdb4946 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -11,7 +11,7 @@ 
 #pragma once
 
 #include "root/root.h"
-
+#include "ast_node.h"
 #include "globals.h"
 #include "arraytypes.h"
 #include "visitor.h"
@@ -29,7 +29,7 @@  class ExpInitializer;
 
 enum NeedInterpret { INITnointerpret, INITinterpret };
 
-class Initializer : public RootObject
+class Initializer : public ASTNode
 {
 public:
     Loc loc;
@@ -45,7 +45,7 @@  public:
     virtual StructInitializer  *isStructInitializer()  { return NULL; }
     virtual ArrayInitializer   *isArrayInitializer()  { return NULL; }
     virtual ExpInitializer     *isExpInitializer()  { return NULL; }
-    virtual void accept(Visitor *v) { v->visit(this); }
+    void accept(Visitor *v) { v->visit(this); }
 };
 
 class VoidInitializer : public Initializer
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 011aff7ec93..b07ce159912 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -2328,6 +2328,106 @@  TypeBasic *Type::isTypeBasic()
     return NULL;
 }
 
+TypeError *Type::isTypeError()
+{
+    return ty == Terror ? (TypeError *)this : NULL;
+}
+
+TypeVector *Type::isTypeVector()
+{
+    return ty == Tvector ? (TypeVector *)this : NULL;
+}
+
+TypeSArray *Type::isTypeSArray()
+{
+    return ty == Tsarray ? (TypeSArray *)this : NULL;
+}
+
+TypeDArray *Type::isTypeDArray()
+{
+    return ty == Tarray ? (TypeDArray *)this : NULL;
+}
+
+TypeAArray *Type::isTypeAArray()
+{
+    return ty == Taarray ? (TypeAArray *)this : NULL;
+}
+
+TypePointer *Type::isTypePointer()
+{
+    return ty == Tpointer ? (TypePointer *)this : NULL;
+}
+
+TypeReference *Type::isTypeReference()
+{
+    return ty == Treference ? (TypeReference *)this : NULL;
+}
+
+TypeFunction *Type::isTypeFunction()
+{
+    return ty == Tfunction ? (TypeFunction *)this : NULL;
+}
+
+TypeDelegate *Type::isTypeDelegate()
+{
+    return ty == Tdelegate ? (TypeDelegate *)this : NULL;
+}
+
+TypeIdentifier *Type::isTypeIdentifier()
+{
+    return ty == Tident ? (TypeIdentifier *)this : NULL;
+}
+
+TypeInstance *Type::isTypeInstance()
+{
+    return ty == Tinstance ? (TypeInstance *)this : NULL;
+}
+
+TypeTypeof *Type::isTypeTypeof()
+{
+    return ty == Ttypeof ? (TypeTypeof *)this : NULL;
+}
+
+TypeReturn *Type::isTypeReturn()
+{
+    return ty == Treturn ? (TypeReturn *)this : NULL;
+}
+
+TypeStruct *Type::isTypeStruct()
+{
+    return ty == Tstruct ? (TypeStruct *)this : NULL;
+}
+
+TypeEnum *Type::isTypeEnum()
+{
+    return ty == Tenum ? (TypeEnum *)this : NULL;
+}
+
+TypeClass *Type::isTypeClass()
+{
+    return ty == Tclass ? (TypeClass *)this : NULL;
+}
+
+TypeTuple *Type::isTypeTuple()
+{
+    return ty == Ttuple ? (TypeTuple *)this : NULL;
+}
+
+TypeSlice *Type::isTypeSlice()
+{
+    return ty == Tslice ? (TypeSlice *)this : NULL;
+}
+
+TypeNull *Type::isTypeNull()
+{
+    return ty == Tnull ? (TypeNull *)this : NULL;
+}
+
+TypeTraits *Type::isTypeTraits()
+{
+    return ty == Ttraits ? (TypeTraits *)this : NULL;
+}
+
 TypeFunction *Type::toTypeFunction()
 {
     if (ty != Tfunction)
@@ -3688,7 +3788,7 @@  TypeVector::TypeVector(Type *basetype)
     this->basetype = basetype;
 }
 
-TypeVector *TypeVector::create(Loc, Type *basetype)
+TypeVector *TypeVector::create(Type *basetype)
 {
     return new TypeVector(basetype);
 }
@@ -8578,7 +8678,7 @@  L1:
             return e;
         }
 
-        if (ident == Id::__monitor)
+        if (ident == Id::__monitor && sym->hasMonitor())
         {
             /* The handle to the monitor (call it a void*)
              * *(cast(void**)e + 1)
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 89105d93e3f..4e28deadea7 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -15,6 +15,7 @@ 
 #include "root/dcompat.h" // for d_size_t
 
 #include "arraytypes.h"
+#include "ast_node.h"
 #include "expression.h"
 #include "visitor.h"
 
@@ -134,7 +135,7 @@  enum VarArg
                          ///   or https://dlang.org/spec/function.html#typesafe_variadic_functions
 };
 
-class Type : public RootObject
+class Type : public ASTNode
 {
 public:
     TY ty;
@@ -348,7 +349,28 @@  public:
 
     // For eliminating dynamic_cast
     virtual TypeBasic *isTypeBasic();
-    virtual void accept(Visitor *v) { v->visit(this); }
+    TypeError *isTypeError();
+    TypeVector *isTypeVector();
+    TypeSArray *isTypeSArray();
+    TypeDArray *isTypeDArray();
+    TypeAArray *isTypeAArray();
+    TypePointer *isTypePointer();
+    TypeReference *isTypeReference();
+    TypeFunction *isTypeFunction();
+    TypeDelegate *isTypeDelegate();
+    TypeIdentifier *isTypeIdentifier();
+    TypeInstance *isTypeInstance();
+    TypeTypeof *isTypeTypeof();
+    TypeReturn *isTypeReturn();
+    TypeStruct *isTypeStruct();
+    TypeEnum *isTypeEnum();
+    TypeClass *isTypeClass();
+    TypeTuple *isTypeTuple();
+    TypeSlice *isTypeSlice();
+    TypeNull *isTypeNull();
+    TypeTraits *isTypeTraits();
+
+    void accept(Visitor *v) { v->visit(this); }
 };
 
 class TypeError : public Type
@@ -424,7 +446,7 @@  public:
     Type *basetype;
 
     TypeVector(Type *basetype);
-    static TypeVector *create(Loc loc, Type *basetype);
+    static TypeVector *create(Type *basetype);
     const char *kind();
     Type *syntaxCopy();
     Type *semantic(Loc loc, Scope *sc);
@@ -595,7 +617,7 @@  enum PURE
     PUREstrong = 4      // parameters are values or immutable
 };
 
-class Parameter : public RootObject
+class Parameter : public ASTNode
 {
 public:
     StorageClass storageClass;
@@ -609,7 +631,7 @@  public:
     Type *isLazyArray();
     // kludge for template.isType()
     int dyncast() const { return DYNCAST_PARAMETER; }
-    virtual void accept(Visitor *v) { v->visit(this); }
+    void accept(Visitor *v) { v->visit(this); }
 
     static Parameters *arraySyntaxCopy(Parameters *parameters);
     static size_t dim(Parameters *parameters);
diff --git a/gcc/d/dmd/root/port.h b/gcc/d/dmd/root/port.h
index c51c3136f04..b35da253072 100644
--- a/gcc/d/dmd/root/port.h
+++ b/gcc/d/dmd/root/port.h
@@ -32,10 +32,10 @@  struct Port
     static bool isFloat64LiteralOutOfRange(const char *s);
 
     static void writelongLE(unsigned value, void *buffer);
-    static unsigned readlongLE(void *buffer);
+    static unsigned readlongLE(const void *buffer);
     static void writelongBE(unsigned value, void *buffer);
-    static unsigned readlongBE(void *buffer);
-    static unsigned readwordLE(void *buffer);
-    static unsigned readwordBE(void *buffer);
+    static unsigned readlongBE(const void *buffer);
+    static unsigned readwordLE(const void *buffer);
+    static unsigned readwordBE(const void *buffer);
     static void valcpy(void *dst, uint64_t val, size_t size);
 };
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index 1fc1e980bd9..c8aa4d343aa 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -13,6 +13,7 @@ 
 #include "root/root.h"
 
 #include "arraytypes.h"
+#include "ast_node.h"
 #include "dsymbol.h"
 #include "visitor.h"
 #include "tokens.h"
@@ -66,7 +67,7 @@  enum BE
     BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt)
 };
 
-class Statement : public RootObject
+class Statement : public ASTNode
 {
 public:
     Loc loc;
@@ -105,7 +106,7 @@  public:
     virtual BreakStatement *isBreakStatement() { return NULL; }
     virtual DtorExpStatement *isDtorExpStatement() { return NULL; }
     virtual ForwardingStatement *isForwardingStatement() { return NULL; }
-    virtual void accept(Visitor *v) { v->visit(this); }
+    void accept(Visitor *v) { v->visit(this); }
 };
 
 /** Any Statement that fails semantic() or has a component that is an ErrorExp or
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index c0cd36c9508..0a5bc798d6b 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -119,7 +119,7 @@  public:
  * For this-parameter:
  *  template Foo(this ident)
  */
-class TemplateParameter
+class TemplateParameter : public ASTNode
 {
 public:
     Loc loc;
@@ -159,7 +159,7 @@  public:
     /* Create dummy argument based on parameter.
      */
     virtual void *dummyArg() = 0;
-    virtual void accept(Visitor *v) { v->visit(this); }
+    void accept(Visitor *v) { v->visit(this); }
 };
 
 /* Syntax:
diff --git a/gcc/d/dmd/utf.c b/gcc/d/dmd/utf.c
index 7f496e138fe..c497f961315 100644
--- a/gcc/d/dmd/utf.c
+++ b/gcc/d/dmd/utf.c
@@ -113,15 +113,16 @@  bool isUniAlpha(dchar_t c)
 
 int utf_codeLengthChar(dchar_t c)
 {
-  if (c <= 0x7F)
-      return 1;
-  if (c <= 0x7FF)
-      return 2;
-  if (c <= 0xFFFF)
-      return 3;
-  if (c <= 0x10FFFF)
-      return 4;
-  assert(false);
+    if (c <= 0x7F)
+        return 1;
+    if (c <= 0x7FF)
+        return 2;
+    if (c <= 0xFFFF)
+        return 3;
+    if (c <= 0x10FFFF)
+        return 4;
+    assert(false);
+    return 6;
 }
 
 int utf_codeLengthWchar(dchar_t c)