diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 61014cbea51..cbc74558106 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dmd/identifier.h"
 #include "dmd/module.h"
 #include "dmd/mtype.h"
+#include "dmd/target.h"
 
 #include "tree.h"
 #include "fold-const.h"
@@ -67,7 +68,7 @@ static vec<builtin_data> builtin_converted_decls;
    as casting from `C char' to `D char', which also means that `char *`
    needs to be specially handled.  */
 
-static Type *
+Type *
 build_frontend_type (tree type)
 {
   Type *dtype;
@@ -598,14 +599,12 @@ d_build_builtins_module (Module *m)
 	}
     }
 
-  /* va_list should already be built, so no need to convert to D type again.  */
-  StructDeclaration *sd = (Type::tvalist->ty == Tstruct)
-    ? ((TypeStruct *) Type::tvalist)->sym : NULL;
+  /* Expose target-specific va_list type.  */
+  Type *tvalist = target.va_listType (Loc (), NULL);
+  StructDeclaration *sd = (tvalist->ty == Tstruct)
+    ? ((TypeStruct *) tvalist)->sym : NULL;
   if (sd == NULL || !sd->isAnonymous ())
-    {
-      members->push (build_alias_declaration ("__builtin_va_list",
-					      Type::tvalist));
-    }
+    members->push (build_alias_declaration ("__builtin_va_list", tvalist));
   else
     {
       sd->ident = Identifier::idPool ("__builtin_va_list");
@@ -1152,16 +1151,6 @@ d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
 void
 d_init_builtins (void)
 {
-  /* Build the "standard" abi va_list.  */
-  Type::tvalist = build_frontend_type (va_list_type_node);
-  if (!Type::tvalist)
-    sorry ("cannot represent built-in %<va_list%> type in D");
-
-  /* Map the va_list type to the D frontend Type.  This is to prevent both
-     errors in gimplification or an ICE in targetm.canonical_va_list_type.  */
-  Type::tvalist->ctype = va_list_type_node;
-  TYPE_LANG_SPECIFIC (va_list_type_node) = build_lang_type (Type::tvalist);
-
   d_build_c_type_nodes ();
   d_build_d_type_nodes ();
 
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 2337c1dfa3d..cf98d4be7e9 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -362,7 +362,7 @@ build_interface_binfo (tree super, ClassDeclaration *cd, unsigned& offset)
   /* Want RECORD_TYPE, not POINTER_TYPE.  */
   BINFO_TYPE (binfo) = TREE_TYPE (ctype);
   BINFO_INHERITANCE_CHAIN (binfo) = super;
-  BINFO_OFFSET (binfo) = size_int (offset * Target::ptrsize);
+  BINFO_OFFSET (binfo) = size_int (offset * target.ptrsize);
   BINFO_VIRTUAL_P (binfo) = 1;
 
   for (size_t i = 0; i < cd->baseclasses->length; i++, offset++)
@@ -499,7 +499,7 @@ build_vindex_ref (tree object, tree fntype, size_t index)
 
   gcc_assert (POINTER_TYPE_P (fntype));
 
-  return build_memref (fntype, result, size_int (Target::ptrsize * index));
+  return build_memref (fntype, result, size_int (target.ptrsize * index));
 }
 
 /* Return TRUE if EXP is a valid lvalue.  Lvalue references cannot be
@@ -819,7 +819,7 @@ identity_compare_p (StructDeclaration *sd)
 
       /* Check for types that may have padding.  */
       if ((tb->ty == Tcomplex80 || tb->ty == Tfloat80 || tb->ty == Timaginary80)
-	  && Target::realpad != 0)
+	  && target.realpad != 0)
 	return false;
 
       if (offset <= vd->offset)
diff --git a/gcc/d/d-ctfloat.cc b/gcc/d/d-ctfloat.cc
index f2243d4a45e..606bcf524bd 100644
--- a/gcc/d/d-ctfloat.cc
+++ b/gcc/d/d-ctfloat.cc
@@ -92,7 +92,7 @@ CTFloat::parse (const char *buffer, bool *overflow)
   real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node));
 
   /* Front-end checks overflow to see if the value is representable.  */
-  if (overflow && r == Target::RealProperties::infinity)
+  if (overflow && r == target.RealProperties.infinity)
     *overflow = true;
 
   return r;
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 35197e97a4c..51a87a01813 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -387,7 +387,7 @@ d_init (void)
   /* This is the C main, not the D main.  */
   main_identifier_node = get_identifier ("main");
 
-  Target::_init ();
+  target._init (global.params);
   d_init_versions ();
 
   /* Insert all library-configured identifiers and import paths.  */
diff --git a/gcc/d/d-port.cc b/gcc/d/d-port.cc
index 12208a9039f..f129fd8843d 100644
--- a/gcc/d/d-port.cc
+++ b/gcc/d/d-port.cc
@@ -78,7 +78,7 @@ Port::isFloat32LiteralOutOfRange (const char *buffer)
 
   real_from_string3 (&r.rv (), buffer, TYPE_MODE (float_type_node));
 
-  return r == Target::RealProperties::infinity;
+  return r == target.RealProperties.infinity;
 }
 
 /* Return true if the real_t value from string BUFFER overflows
@@ -91,7 +91,7 @@ Port::isFloat64LiteralOutOfRange (const char *buffer)
 
   real_from_string3 (&r.rv (), buffer, TYPE_MODE (double_type_node));
 
-  return r == Target::RealProperties::infinity;
+  return r == target.RealProperties.infinity;
 }
 
 /* Fetch a little-endian 16-bit value from BUFFER.  */
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index b2df2660579..29f5eaf5c28 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -42,37 +42,14 @@ along with GCC; see the file COPYING3.  If not see
 /* Implements the Target interface defined by the front end.
    Used for retrieving target-specific information.  */
 
-/* Type size information used by frontend.  */
-int Target::ptrsize;
-int Target::c_longsize;
-int Target::realsize;
-int Target::realpad;
-int Target::realalignsize;
-bool Target::reverseCppOverloads;
-bool Target::cppExceptions;
-int Target::classinfosize;
-unsigned long long Target::maxStaticDataSize;
-
-/* Floating-point constants for .max, .min, and other properties.  */
-template <typename T> real_t Target::FPTypeProperties<T>::max;
-template <typename T> real_t Target::FPTypeProperties<T>::min_normal;
-template <typename T> real_t Target::FPTypeProperties<T>::nan;
-template <typename T> real_t Target::FPTypeProperties<T>::snan;
-template <typename T> real_t Target::FPTypeProperties<T>::infinity;
-template <typename T> real_t Target::FPTypeProperties<T>::epsilon;
-template <typename T> d_int64 Target::FPTypeProperties<T>::dig;
-template <typename T> d_int64 Target::FPTypeProperties<T>::mant_dig;
-template <typename T> d_int64 Target::FPTypeProperties<T>::max_exp;
-template <typename T> d_int64 Target::FPTypeProperties<T>::min_exp;
-template <typename T> d_int64 Target::FPTypeProperties<T>::max_10_exp;
-template <typename T> d_int64 Target::FPTypeProperties<T>::min_10_exp;
+Target target;
 
 
 /* Initialize the floating-point constants for TYPE.  */
 
 template <typename T>
 static void
-define_float_constants (tree type)
+define_float_constants (T &f, tree type)
 {
   const double log10_2 = 0.30102999566398119521;
   char buf[128];
@@ -83,106 +60,109 @@ define_float_constants (tree type)
 
   /* The largest representable value that's not infinity.  */
   get_max_float (fmt, buf, sizeof (buf), false);
-  real_from_string (&T::max.rv (), buf);
+  real_from_string (&f.max.rv (), buf);
 
   /* The smallest representable normalized value that's not 0.  */
   snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - 1);
-  real_from_string (&T::min_normal.rv (), buf);
+  real_from_string (&f.min_normal.rv (), buf);
 
   /* Floating-point NaN.  */
-  real_nan (&T::nan.rv (), "", 1, mode);
+  real_nan (&f.nan.rv (), "", 1, mode);
 
   /* Signalling floating-point NaN.  */
-  real_nan (&T::snan.rv (), "", 0, mode);
+  real_nan (&f.snan.rv (), "", 0, mode);
 
   /* Floating-point +Infinity if the target supports infinities.  */
-  real_inf (&T::infinity.rv ());
+  real_inf (&f.infinity.rv ());
 
   /* The smallest increment to the value 1.  */
   if (fmt->pnan < fmt->p)
     snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - fmt->p);
   else
     snprintf (buf, sizeof (buf), "0x1p%d", 1 - fmt->p);
-  real_from_string (&T::epsilon.rv (), buf);
+  real_from_string (&f.epsilon.rv (), buf);
 
   /* The number of decimal digits of precision.  */
-  T::dig = (fmt->p - 1) * log10_2;
+  f.dig = (fmt->p - 1) * log10_2;
 
   /* The number of bits in mantissa.  */
-  T::mant_dig = fmt->p;
+  f.mant_dig = fmt->p;
 
   /* The maximum int value such that 2** (value-1) is representable.  */
-  T::max_exp = fmt->emax;
+  f.max_exp = fmt->emax;
 
   /* The minimum int value such that 2** (value-1) is representable as a
      normalized value.  */
-  T::min_exp = fmt->emin;
+  f.min_exp = fmt->emin;
 
   /* The maximum int value such that 10**value is representable.  */
-  T::max_10_exp = fmt->emax * log10_2;
+  f.max_10_exp = fmt->emax * log10_2;
 
   /* The minimum int value such that 10**value is representable as a
      normalized value.  */
-  T::min_10_exp = (fmt->emin - 1) * log10_2;
+  f.min_10_exp = (fmt->emin - 1) * log10_2;
 }
 
 /* Initialize all variables of the Target structure.  */
 
 void
-Target::_init (void)
+Target::_init (const Param &)
 {
   /* Map D frontend type and sizes to GCC back-end types.  */
-  Target::ptrsize = (POINTER_SIZE / BITS_PER_UNIT);
-  Target::realsize = int_size_in_bytes (long_double_type_node);
-  Target::realpad = (Target::realsize -
-		     (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT));
-  Target::realalignsize = TYPE_ALIGN_UNIT (long_double_type_node);
+  this->ptrsize = (POINTER_SIZE / BITS_PER_UNIT);
+  this->realsize = int_size_in_bytes (long_double_type_node);
+  this->realpad = (this->realsize -
+		   (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT));
+  this->realalignsize = TYPE_ALIGN_UNIT (long_double_type_node);
 
   /* Size of run-time TypeInfo object.  */
-  Target::classinfosize = 19 * Target::ptrsize;
+  this->classinfosize = 19 * this->ptrsize;
 
   /* Much of the dmd front-end uses ints for sizes and offsets, and cannot
      handle any larger data type without some pervasive rework.  */
-  Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (integer_type_node));
+  this->maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (integer_type_node));
 
   /* Define what type to use for size_t, ptrdiff_t.  */
-  if (Target::ptrsize == 8)
+  if (this->ptrsize == 8)
     {
       global.params.isLP64 = true;
-      Tsize_t = Tuns64;
-      Tptrdiff_t = Tint64;
+      Type::tsize_t = Type::basic[Tuns64];
+      Type::tptrdiff_t = Type::basic[Tint64];
     }
-  else if (Target::ptrsize == 4)
+  else if (this->ptrsize == 4)
     {
-      Tsize_t = Tuns32;
-      Tptrdiff_t = Tint32;
+      Type::tsize_t = Type::basic[Tuns32];
+      Type::tptrdiff_t = Type::basic[Tint32];
     }
-  else if (Target::ptrsize == 2)
+  else if (this->ptrsize == 2)
     {
-      Tsize_t = Tuns16;
-      Tptrdiff_t = Tint16;
+      Type::tsize_t = Type::basic[Tuns16];
+      Type::tptrdiff_t = Type::basic[Tint16];
     }
   else
     sorry ("D does not support pointers on this target.");
 
-  Type::tsize_t = Type::basic[Tsize_t];
-  Type::tptrdiff_t = Type::basic[Tptrdiff_t];
   Type::thash_t = Type::tsize_t;
 
   /* Set-up target C ABI.  */
-  Target::c_longsize = int_size_in_bytes (long_integer_type_node);
+  this->c.longsize = int_size_in_bytes (long_integer_type_node);
+  this->c.long_doublesize = int_size_in_bytes (long_double_type_node);
 
   /* Set-up target C++ ABI.  */
-  Target::reverseCppOverloads = false;
-  Target::cppExceptions = true;
+  this->cpp.reverseOverloads = false;
+  this->cpp.exceptions = true;
+  this->cpp.twoDtorInVtable = true;
+
+  /* Set-up target Objective-C ABI.  */
+  this->objc.supported = false;
 
   /* Initialize all compile-time properties for floating-point types.
      Should ensure that our real_t type is able to represent real_value.  */
   gcc_assert (sizeof (real_t) >= sizeof (real_value));
 
-  define_float_constants <Target::FloatProperties> (float_type_node);
-  define_float_constants <Target::DoubleProperties> (double_type_node);
-  define_float_constants <Target::RealProperties> (long_double_type_node);
+  define_float_constants (this->FloatProperties, float_type_node);
+  define_float_constants (this->DoubleProperties, double_type_node);
+  define_float_constants (this->RealProperties, long_double_type_node);
 
   /* Commonly used floating-point constants.  */
   const machine_mode mode = TYPE_MODE (long_double_type_node);
@@ -238,9 +218,22 @@ Target::critsecsize (void)
 /* Returns a Type for the va_list type of the target.  */
 
 Type *
-Target::va_listType (void)
+Target::va_listType (const Loc &, Scope *)
 {
-  return Type::tvalist;
+  if (this->tvalist)
+    return this->tvalist;
+
+  /* Build the "standard" abi va_list.  */
+  this->tvalist = build_frontend_type (va_list_type_node);
+  if (!this->tvalist)
+    sorry ("cannot represent built-in %<va_list%> type in D");
+
+  /* Map the va_list type to the D frontend Type.  This is to prevent both
+     errors in gimplification or an ICE in targetm.canonical_va_list_type.  */
+  this->tvalist->ctype = va_list_type_node;
+  TYPE_LANG_SPECIFIC (va_list_type_node) = build_lang_type (this->tvalist);
+
+  return this->tvalist;
 }
 
 /* Checks whether the target supports a vector type with total size SZ
@@ -335,7 +328,7 @@ Target::isVectorOpSupported (Type *type, TOK op, Type *)
 /* Return the symbol mangling of S for C++ linkage.  */
 
 const char *
-Target::toCppMangle (Dsymbol *s)
+TargetCPP::toMangle (Dsymbol *s)
 {
   return toCppMangleItanium (s);
 }
@@ -343,7 +336,7 @@ Target::toCppMangle (Dsymbol *s)
 /* Return the symbol mangling of CD for C++ linkage.  */
 
 const char *
-Target::cppTypeInfoMangle (ClassDeclaration *cd)
+TargetCPP::typeInfoMangle (ClassDeclaration *cd)
 {
   return cppTypeInfoMangleItanium (cd);
 }
@@ -352,7 +345,7 @@ Target::cppTypeInfoMangle (ClassDeclaration *cd)
    In all other cases, return NULL.  */
 
 const char *
-Target::cppTypeMangle (Type *type)
+TargetCPP::typeMangle (Type *type)
 {
   if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct)
     {
@@ -367,7 +360,7 @@ Target::cppTypeMangle (Type *type)
    ARG to an extern(C++) function.  */
 
 Type *
-Target::cppParameterType (Parameter *arg)
+TargetCPP::parameterType (Parameter *arg)
 {
   Type *t = arg->type->merge2 ();
   if (arg->storageClass & (STCout | STCref))
@@ -381,10 +374,11 @@ Target::cppParameterType (Parameter *arg)
     }
 
   /* Could be a va_list, which we mangle as a pointer.  */
-  if (t->ty == Tsarray && Type::tvalist->ty == Tsarray)
+  Type *tvalist = target.va_listType (Loc (), NULL);
+  if (t->ty == Tsarray && tvalist->ty == Tsarray)
     {
       Type *tb = t->toBasetype ()->mutableOf ();
-      if (tb == Type::tvalist)
+      if (tb == tvalist)
 	{
 	  tb = t->nextOf ()->pointerTo ();
 	  t = tb->castMod (t->mod);
@@ -398,7 +392,7 @@ Target::cppParameterType (Parameter *arg)
    in IS_FUNDAMENTAL and returns true if the parameter was set.  */
 
 bool
-Target::cppFundamentalType (const Type *, bool &)
+TargetCPP::fundamentalType (const Type *, bool &)
 {
   return false;
 }
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 33022055e3e..3338e88b278 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -489,6 +489,7 @@ extern void apply_user_attributes (Dsymbol *, tree);
 /* In d-builtins.cc.  */
 extern const attribute_spec d_langhook_attribute_table[];
 extern const attribute_spec d_langhook_common_attribute_table[];
+extern Type *build_frontend_type (tree);
 
 extern tree d_builtin_function (tree);
 extern void d_init_builtins (void);
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index d5f8797b55e..f2d39a74cc8 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -2011,7 +2011,7 @@ mark_needed (tree decl)
 unsigned
 base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
 {
-  unsigned csymoffset = Target::classinfosize;
+  unsigned csymoffset = target.classinfosize;
   unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);
   csymoffset += cd->vtblInterfaces->length * interfacesize;
 
@@ -2020,7 +2020,7 @@ base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
       BaseClass *b = (*cd->vtblInterfaces)[i];
       if (b == bc)
 	return csymoffset;
-      csymoffset += b->sym->vtbl.length * Target::ptrsize;
+      csymoffset += b->sym->vtbl.length * target.ptrsize;
     }
 
   /* Check all overriding interface vtbl[]s.  */
@@ -2033,7 +2033,7 @@ base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
 	    {
 	      if (bc == bs)
 		return csymoffset;
-	      csymoffset += bs->sym->vtbl.length * Target::ptrsize;
+	      csymoffset += bs->sym->vtbl.length * target.ptrsize;
 	    }
 	}
     }
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 0a4fb767396..f413bd17514 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-6d5bffa54f7da21d388d9999e586fd8a11ebcdb1
+56f0a65c493463633a293d71faf37cdf710041ef
 
 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/attrib.c b/gcc/d/dmd/attrib.c
index 02761ab0355..184af1f288c 100644
--- a/gcc/d/dmd/attrib.c
+++ b/gcc/d/dmd/attrib.c
@@ -516,7 +516,7 @@ LinkDeclaration::LinkDeclaration(LINK p, Dsymbols *decl)
         : AttribDeclaration(decl)
 {
     //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
-    linkage = (p == LINKsystem) ? Target::systemLinkage() : p;
+    linkage = (p == LINKsystem) ? target.systemLinkage() : p;
 }
 
 LinkDeclaration *LinkDeclaration::create(LINK p, Dsymbols *decl)
diff --git a/gcc/d/dmd/constfold.c b/gcc/d/dmd/constfold.c
index a0364ef8c90..38e6191698d 100644
--- a/gcc/d/dmd/constfold.c
+++ b/gcc/d/dmd/constfold.c
@@ -623,7 +623,7 @@ UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2)
         // x ^^ y for x < 0 and y not an integer is not defined; so set result as NaN
         if (e1->toReal() < CTFloat::zero)
         {
-            new(&ue) RealExp(loc, Target::RealProperties::nan, type);
+            new(&ue) RealExp(loc, target.RealProperties.nan, type);
         }
         else
             new(&ue) CTFEExp(TOKcantexp);
diff --git a/gcc/d/dmd/cppmangle.c b/gcc/d/dmd/cppmangle.c
index a50802225aa..f39c2484460 100644
--- a/gcc/d/dmd/cppmangle.c
+++ b/gcc/d/dmd/cppmangle.c
@@ -131,7 +131,7 @@ class CppMangleVisitor : public Visitor
     {
         // First check the target whether some specific ABI is being followed.
         bool isFundamental;
-        if (Target::cppFundamentalType(t, isFundamental))
+        if (target.cpp.fundamentalType(t, isFundamental))
             return isFundamental;
         if (t->ty == Tenum)
         {
@@ -672,7 +672,7 @@ class CppMangleVisitor : public Visitor
             {
                 ParamsCppMangle *p = (ParamsCppMangle *)ctx;
                 CppMangleVisitor *mangler = p->mangler;
-                Type *t = Target::cppParameterType(fparam);
+                Type *t = target.cpp.parameterType(fparam);
                 if (t->ty == Tsarray)
                 {
                     // Static arrays in D are passed by value; no counterpart in C++
@@ -803,7 +803,7 @@ public:
             return error(t);
 
         // Handle any target-specific basic types.
-        if (const char *tm = Target::cppTypeMangle(t))
+        if (const char *tm = target.cpp.typeMangle(t))
         {
             // Only do substitutions for non-fundamental types.
             if (!isFundamentalType(t) || t->isConst())
@@ -862,10 +862,10 @@ public:
             case Tuns32:                c = 'j';        break;
             case Tfloat32:              c = 'f';        break;
             case Tint64:
-                c = (Target::c_longsize == 8 ? 'l' : 'x');
+                c = (target.c.longsize == 8 ? 'l' : 'x');
                 break;
             case Tuns64:
-                c = (Target::c_longsize == 8 ? 'm' : 'y');
+                c = (target.c.longsize == 8 ? 'm' : 'y');
                 break;
             case Tint128:                c = 'n';       break;
             case Tuns128:                c = 'o';       break;
@@ -899,7 +899,7 @@ public:
         CV_qualifiers(t);
 
         // Handle any target-specific vector types.
-        if (const char *tm = Target::cppTypeMangle(t))
+        if (const char *tm = target.cpp.typeMangle(t))
         {
             buf->writestring(tm);
         }
@@ -1030,7 +1030,7 @@ public:
         CV_qualifiers(t);
 
         // Handle any target-specific struct types.
-        if (const char *tm = Target::cppTypeMangle(t))
+        if (const char *tm = target.cpp.typeMangle(t))
         {
             buf->writestring(tm);
         }
diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c
index 754a996ff50..535679e10be 100644
--- a/gcc/d/dmd/dclass.c
+++ b/gcc/d/dmd/dclass.c
@@ -1048,7 +1048,7 @@ static unsigned membersPlace(BaseClasses *vtblInterfaces, size_t &bi, ClassDecla
         assert(b->sym->sizeok == SIZEOKdone);
 
         if (!b->sym->alignsize)
-            b->sym->alignsize = Target::ptrsize;
+            b->sym->alignsize = target.ptrsize;
         cd->alignmember(b->sym->alignsize, b->sym->alignsize, &offset);
         assert(bi < vtblInterfaces->length);
         BaseClass *bv = (*vtblInterfaces)[bi];
@@ -1092,16 +1092,16 @@ void ClassDeclaration::finalizeSize()
     {
         if (interfaces.length == 0)
         {
-            alignsize = Target::ptrsize;
-            structsize = Target::ptrsize;      // allow room for __vptr
+            alignsize = target.ptrsize;
+            structsize = target.ptrsize;      // allow room for __vptr
         }
     }
     else
     {
-        alignsize = Target::ptrsize;
-        structsize = Target::ptrsize;      // allow room for __vptr
+        alignsize = target.ptrsize;
+        structsize = target.ptrsize;      // allow room for __vptr
         if (!isCPPclass())
-            structsize += Target::ptrsize; // allow room for __monitor
+            structsize += target.ptrsize; // allow room for __monitor
     }
 
     //printf("finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
diff --git a/gcc/d/dmd/declaration.c b/gcc/d/dmd/declaration.c
index 5ae8c06e7ec..04f7a34ea97 100644
--- a/gcc/d/dmd/declaration.c
+++ b/gcc/d/dmd/declaration.c
@@ -1778,7 +1778,7 @@ void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset,
     const d_uns64 sz = t->size(loc);
     assert(sz != SIZE_INVALID && sz < UINT32_MAX);
     unsigned memsize = (unsigned)sz;                 // size of member
-    unsigned memalignsize = Target::fieldalign(t);   // size of member for alignment purposes
+    unsigned memalignsize = target.fieldalign(t);   // size of member for alignment purposes
 
     offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment,
                 &ad->structsize, &ad->alignsize, isunion);
@@ -2220,7 +2220,7 @@ TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo)
     storage_class = STCstatic | STCgshared;
     protection = Prot(PROTpublic);
     linkage = LINKc;
-    alignment = Target::ptrsize;
+    alignment = target.ptrsize;
 }
 
 TypeInfoDeclaration *TypeInfoDeclaration::create(Type *tinfo)
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index 18bdf27de56..c1a186de645 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -421,7 +421,7 @@ public:
                     return;
 
                 case LINKcpp:
-                    buf->writestring(Target::toCppMangle(d));
+                    buf->writestring(target.cpp.toMangle(d));
                     return;
 
                 case LINKdefault:
diff --git a/gcc/d/dmd/dstruct.c b/gcc/d/dmd/dstruct.c
index 5af27455724..891d469cebf 100644
--- a/gcc/d/dmd/dstruct.c
+++ b/gcc/d/dmd/dstruct.c
@@ -799,7 +799,7 @@ void AggregateDeclaration::alignmember(
             break;
 
         case (structalign_t) STRUCTALIGN_DEFAULT:
-            // Alignment in Target::fieldalignsize must match what the
+            // Alignment in target.fieldalignsize must match what the
             // corresponding C compiler's default alignment behavior is.
             assert(size > 0 && !(size & (size - 1)));
             *poffset = (*poffset + size - 1) & ~(size - 1);
@@ -1307,7 +1307,7 @@ void StructDeclaration::finalizeSize()
         }
     }
 
-    TypeTuple *tt = Target::toArgTypes(type);
+    TypeTuple *tt = target.toArgTypes(type);
     size_t dim = tt ? tt->arguments->length : 0;
     if (dim >= 1)
     {
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index 0b042732da8..29103c1bac3 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -2925,11 +2925,11 @@ void IntegerExp::normalize()
         case Tint64:        value = (d_int64) value;        break;
         case Tuns64:        value = (d_uns64) value;        break;
         case Tpointer:
-            if (Target::ptrsize == 8)
+            if (target.ptrsize == 8)
                 value = (d_uns64) value;
-            else if (Target::ptrsize == 4)
+            else if (target.ptrsize == 4)
                 value = (d_uns32) value;
-            else if (Target::ptrsize == 2)
+            else if (target.ptrsize == 2)
                 value = (d_uns16) value;
             else
                 assert(0);
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index cec57d4a8e6..ffcfeb4e6cd 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -2073,7 +2073,7 @@ public:
                      * The results of this are highly platform dependent, and intended
                      * primarly for use in implementing va_arg().
                      */
-                    tded = Target::toArgTypes(e->targ);
+                    tded = target.toArgTypes(e->targ);
                     if (!tded)
                         goto Lno;           // not valid for a parameter
                     break;
@@ -2295,7 +2295,7 @@ public:
                 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt);
         }
 
-        if (!Target::isVectorOpSupported(exp->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(exp->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -3917,7 +3917,7 @@ public:
             return;
         }
 
-        if (!Target::isVectorOpSupported(tb, exp->op))
+        if (!target.isVectorOpSupported(tb, exp->op))
         {
             result = exp->incompatibleTypes();
             return;
@@ -3941,7 +3941,7 @@ public:
             return;
         }
 
-        if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op))
+        if (!target.isVectorOpSupported(exp->e1->type->toBasetype(), exp->op))
         {
             result = exp->incompatibleTypes();
             return;
@@ -3982,7 +3982,7 @@ public:
             return;
         }
 
-        if (!Target::isVectorOpSupported(tb, exp->op))
+        if (!target.isVectorOpSupported(tb, exp->op))
         {
             result = exp->incompatibleTypes();
             return;
@@ -4024,7 +4024,7 @@ public:
             return;
         }
 
-        if (!Target::isVectorOpSupported(e->e1->type->toBasetype(), e->op))
+        if (!target.isVectorOpSupported(e->e1->type->toBasetype(), e->op))
         {
             result = e->incompatibleTypes();
             return;
@@ -6410,7 +6410,7 @@ public:
         }
 
         tb1 = exp->e1->type->toBasetype();
-        if (!Target::isVectorOpSupported(tb1, exp->op, tb2))
+        if (!target.isVectorOpSupported(tb1, exp->op, tb2))
         {
             result = exp->incompatibleTypes();
             return;
@@ -6543,7 +6543,7 @@ public:
 
         t1 = exp->e1->type->toBasetype();
         t2 = exp->e2->type->toBasetype();
-        if (!Target::isVectorOpSupported(t1, exp->op, t2))
+        if (!target.isVectorOpSupported(t1, exp->op, t2))
         {
             result = exp->incompatibleTypes();
             return;
@@ -6864,7 +6864,7 @@ public:
                 exp->type = t1;  // t1 is complex
             }
         }
-        else if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
+        else if (!target.isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -6964,7 +6964,7 @@ public:
                 exp->type = t1;  // t1 is complex
             }
         }
-        else if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
+        else if (!target.isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7009,7 +7009,7 @@ public:
             result = exp;
             return;
         }
-        if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7091,7 +7091,7 @@ public:
         if (exp->checkArithmeticBin())
             return setError();
 
-        if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7191,7 +7191,7 @@ public:
 
         if (exp->checkIntegralBin())
             return setError();
-        if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7226,7 +7226,7 @@ public:
 
         if (exp->checkIntegralBin())
             return setError();
-        if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7261,7 +7261,7 @@ public:
 
         if (exp->checkIntegralBin())
             return setError();
-        if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7320,7 +7320,7 @@ public:
             return;
         }
 
-        if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7377,7 +7377,7 @@ public:
             return;
         }
 
-        if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7434,7 +7434,7 @@ public:
             return;
         }
 
-        if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
+        if (!target.isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7756,7 +7756,7 @@ public:
             exp->error("%s is not defined for associative arrays", Token::toChars(exp->op));
             return setError();
         }
-        else if (!Target::isVectorOpSupported(t1, exp->op, t2))
+        else if (!target.isVectorOpSupported(t1, exp->op, t2))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7905,7 +7905,7 @@ public:
         Type *t1 = exp->e1->type->toBasetype();
         Type *t2 = exp->e2->type->toBasetype();
 
-        if (!Target::isVectorOpSupported(t1, exp->op, t2))
+        if (!target.isVectorOpSupported(t1, exp->op, t2))
         {
             result = exp->incompatibleTypes();
             return;
@@ -7958,7 +7958,7 @@ public:
 
         Type *tb1 = exp->e1->type->toBasetype();
         Type *tb2 = exp->e2->type->toBasetype();
-        if (!Target::isVectorOpSupported(tb1, exp->op, tb2))
+        if (!target.isVectorOpSupported(tb1, exp->op, tb2))
         {
             result = exp->incompatibleTypes();
             return;
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index 961e84a010a..807565df12b 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -902,7 +902,7 @@ void FuncDeclaration::semantic(Scope *sc)
                 {
                     //printf("\tintroducing function %s\n", toChars());
                     introducing = 1;
-                    if (cd->isCPPclass() && Target::reverseCppOverloads)
+                    if (cd->isCPPclass() && target.cpp.reverseOverloads)
                     {
                         // with dmc, overloaded functions are grouped and in reverse order
                         vtblIndex = (int)cd->vtbl.length;
@@ -1553,7 +1553,7 @@ void FuncDeclaration::semantic3(Scope *sc)
             if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters)))
             {
                 // Declare _argptr
-                Type *t = Type::tvalist;
+                Type *t = target.va_listType(loc, sc);
                 v_argptr = new VarDeclaration(Loc(), t, Id::_argptr, NULL);
                 v_argptr->storage_class |= STCtemp;
                 v_argptr->semantic(sc2);
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index 156f4a6df97..d61a244175f 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -2212,11 +2212,11 @@ public:
             if ((sinteger_t)uval >= 0)
             {
                 dinteger_t sizemax;
-                if (Target::ptrsize == 8)
+                if (target.ptrsize == 8)
                     sizemax = 0xFFFFFFFFFFFFFFFFULL;
-                else if (Target::ptrsize == 4)
+                else if (target.ptrsize == 4)
                     sizemax = 0xFFFFFFFFUL;
-                else if (Target::ptrsize == 2)
+                else if (target.ptrsize == 2)
                     sizemax = 0xFFFFUL;
                 else
                     assert(0);
@@ -2358,7 +2358,7 @@ public:
                     buf->writestring("cast(");
                     buf->writestring(t->toChars());
                     buf->writeByte(')');
-                    if (Target::ptrsize == 8)
+                    if (target.ptrsize == 8)
                         goto L4;
                     else
                         goto L3;
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 8223d25be6b..e2511a4fd62 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -44,9 +44,6 @@ Expression *typeToExpression(Type *t);
 Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);
 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
 
-int Tsize_t = Tuns32;
-int Tptrdiff_t = Tint32;
-
 /***************************** Type *****************************/
 
 ClassDeclaration *Type::dtypeinfo;
@@ -109,7 +106,6 @@ Type *Type::tvoidptr;
 Type *Type::tstring;
 Type *Type::twstring;
 Type *Type::tdstring;
-Type *Type::tvalist;
 Type *Type::basic[TMAX];
 unsigned char Type::sizeTy[TMAX];
 StringTable Type::stringtable;
@@ -262,21 +258,11 @@ void Type::_init()
     tstring = tchar->immutableOf()->arrayOf();
     twstring = twchar->immutableOf()->arrayOf();
     tdstring = tdchar->immutableOf()->arrayOf();
-    tvalist = Target::va_listType();
 
-    if (global.params.isLP64)
-    {
-        Tsize_t = Tuns64;
-        Tptrdiff_t = Tint64;
-    }
-    else
-    {
-        Tsize_t = Tuns32;
-        Tptrdiff_t = Tint32;
-    }
+    const bool isLP64 = global.params.isLP64;
 
-    tsize_t = basic[Tsize_t];
-    tptrdiff_t = basic[Tptrdiff_t];
+    tsize_t = basic[isLP64 ? Tuns64 : Tuns32];
+    tptrdiff_t = basic[isLP64 ? Tint64 : Tint32];
     thash_t = tsize_t;
 }
 
@@ -3041,7 +3027,7 @@ d_uns64 TypeBasic::size(Loc)
                         size = 8;       break;
         case Tfloat80:
         case Timaginary80:
-                        size = Target::realsize; break;
+                        size = target.realsize; break;
         case Tcomplex32:
                         size = 8;               break;
         case Tcomplex64:
@@ -3049,7 +3035,7 @@ d_uns64 TypeBasic::size(Loc)
         case Tuns128:
                         size = 16;              break;
         case Tcomplex80:
-                        size = Target::realsize * 2; break;
+                        size = target.realsize * 2; break;
 
         case Tvoid:
             //size = Type::size();      // error message
@@ -3071,7 +3057,7 @@ d_uns64 TypeBasic::size(Loc)
 
 unsigned TypeBasic::alignsize()
 {
-    return Target::alignsize(this);
+    return target.alignsize(this);
 }
 
 
@@ -3125,17 +3111,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            fvalue = Target::FloatProperties::max;
+            fvalue = target.FloatProperties.max;
             goto Lfvalue;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            fvalue = Target::DoubleProperties::max;
+            fvalue = target.DoubleProperties.max;
             goto Lfvalue;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            fvalue = Target::RealProperties::max;
+            fvalue = target.RealProperties.max;
             goto Lfvalue;
         }
     }
@@ -3200,17 +3186,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            fvalue = Target::FloatProperties::min_normal;
+            fvalue = target.FloatProperties.min_normal;
             goto Lfvalue;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            fvalue = Target::DoubleProperties::min_normal;
+            fvalue = target.DoubleProperties.min_normal;
             goto Lfvalue;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            fvalue = Target::RealProperties::min_normal;
+            fvalue = target.RealProperties.min_normal;
             goto Lfvalue;
         }
     }
@@ -3227,7 +3213,7 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tfloat32:
         case Tfloat64:
         case Tfloat80:
-            fvalue = Target::RealProperties::nan;
+            fvalue = target.RealProperties.nan;
             goto Lfvalue;
         }
     }
@@ -3244,7 +3230,7 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tfloat32:
         case Tfloat64:
         case Tfloat80:
-            fvalue = Target::RealProperties::infinity;
+            fvalue = target.RealProperties.infinity;
             goto Lfvalue;
         }
     }
@@ -3255,17 +3241,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            ivalue = Target::FloatProperties::dig;
+            ivalue = target.FloatProperties.dig;
             goto Lint;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            ivalue = Target::DoubleProperties::dig;
+            ivalue = target.DoubleProperties.dig;
             goto Lint;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            ivalue = Target::RealProperties::dig;
+            ivalue = target.RealProperties.dig;
             goto Lint;
         }
     }
@@ -3276,17 +3262,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            fvalue = Target::FloatProperties::epsilon;
+            fvalue = target.FloatProperties.epsilon;
             goto Lfvalue;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            fvalue = Target::DoubleProperties::epsilon;
+            fvalue = target.DoubleProperties.epsilon;
             goto Lfvalue;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            fvalue = Target::RealProperties::epsilon;
+            fvalue = target.RealProperties.epsilon;
             goto Lfvalue;
         }
     }
@@ -3297,17 +3283,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            ivalue = Target::FloatProperties::mant_dig;
+            ivalue = target.FloatProperties.mant_dig;
             goto Lint;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            ivalue = Target::DoubleProperties::mant_dig;
+            ivalue = target.DoubleProperties.mant_dig;
             goto Lint;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            ivalue = Target::RealProperties::mant_dig;
+            ivalue = target.RealProperties.mant_dig;
             goto Lint;
         }
     }
@@ -3318,17 +3304,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            ivalue = Target::FloatProperties::max_10_exp;
+            ivalue = target.FloatProperties.max_10_exp;
             goto Lint;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            ivalue = Target::DoubleProperties::max_10_exp;
+            ivalue = target.DoubleProperties.max_10_exp;
             goto Lint;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            ivalue = Target::RealProperties::max_10_exp;
+            ivalue = target.RealProperties.max_10_exp;
             goto Lint;
         }
     }
@@ -3339,17 +3325,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            ivalue = Target::FloatProperties::max_exp;
+            ivalue = target.FloatProperties.max_exp;
             goto Lint;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            ivalue = Target::DoubleProperties::max_exp;
+            ivalue = target.DoubleProperties.max_exp;
             goto Lint;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            ivalue = Target::RealProperties::max_exp;
+            ivalue = target.RealProperties.max_exp;
             goto Lint;
         }
     }
@@ -3360,17 +3346,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            ivalue = Target::FloatProperties::min_10_exp;
+            ivalue = target.FloatProperties.min_10_exp;
             goto Lint;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            ivalue = Target::DoubleProperties::min_10_exp;
+            ivalue = target.DoubleProperties.min_10_exp;
             goto Lint;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            ivalue = Target::RealProperties::min_10_exp;
+            ivalue = target.RealProperties.min_10_exp;
             goto Lint;
         }
     }
@@ -3381,17 +3367,17 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
         case Tcomplex32:
         case Timaginary32:
         case Tfloat32:
-            ivalue = Target::FloatProperties::min_exp;
+            ivalue = target.FloatProperties.min_exp;
             goto Lint;
         case Tcomplex64:
         case Timaginary64:
         case Tfloat64:
-            ivalue = Target::DoubleProperties::min_exp;
+            ivalue = target.DoubleProperties.min_exp;
             goto Lint;
         case Tcomplex80:
         case Timaginary80:
         case Tfloat80:
-            ivalue = Target::RealProperties::min_exp;
+            ivalue = target.RealProperties.min_exp;
             goto Lint;
         }
     }
@@ -3514,13 +3500,13 @@ Expression *TypeBasic::defaultInit(Loc loc)
         case Tfloat32:
         case Tfloat64:
         case Tfloat80:
-            return new RealExp(loc, Target::RealProperties::snan, this);
+            return new RealExp(loc, target.RealProperties.snan, this);
 
         case Tcomplex32:
         case Tcomplex64:
         case Tcomplex80:
         {   // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).
-            complex_t cvalue = complex_t(Target::RealProperties::snan, Target::RealProperties::snan);
+            complex_t cvalue = complex_t(target.RealProperties.snan, target.RealProperties.snan);
             return new ComplexExp(loc, cvalue, this);
         }
 
@@ -3730,7 +3716,7 @@ Type *TypeVector::semantic(Loc loc, Scope *sc)
     }
     TypeSArray *t = (TypeSArray *)basetype;
     int sz = (int)t->size(loc);
-    switch (Target::isVectorTypeSupported(sz, t->nextOf()))
+    switch (target.isVectorTypeSupported(sz, t->nextOf()))
     {
     case 0: // valid
         break;
@@ -4142,7 +4128,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
         {
         Loverflow:
             error(loc, "%s size %llu * %llu exceeds 0x%llx size limit for static array",
-                toChars(), (unsigned long long)tbn->size(loc), (unsigned long long)d1, Target::maxStaticDataSize);
+                toChars(), (unsigned long long)tbn->size(loc), (unsigned long long)d1, target.maxStaticDataSize);
             goto Lerror;
         }
 
@@ -4166,7 +4152,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
              * run on them for the size, since they may be forward referenced.
              */
             bool overflow = false;
-            if (mulu(tbn->size(loc), d2, overflow) >= Target::maxStaticDataSize || overflow)
+            if (mulu(tbn->size(loc), d2, overflow) >= target.maxStaticDataSize || overflow)
                 goto Loverflow;
         }
     }
@@ -4405,14 +4391,14 @@ Type *TypeDArray::syntaxCopy()
 d_uns64 TypeDArray::size(Loc)
 {
     //printf("TypeDArray::size()\n");
-    return Target::ptrsize * 2;
+    return target.ptrsize * 2;
 }
 
 unsigned TypeDArray::alignsize()
 {
     // A DArray consists of two ptr-sized values, so align it on pointer size
     // boundary
-    return Target::ptrsize;
+    return target.ptrsize;
 }
 
 Type *TypeDArray::semantic(Loc loc, Scope *sc)
@@ -4604,7 +4590,7 @@ Type *TypeAArray::syntaxCopy()
 
 d_uns64 TypeAArray::size(Loc)
 {
-    return Target::ptrsize;
+    return target.ptrsize;
 }
 
 Type *TypeAArray::semantic(Loc loc, Scope *sc)
@@ -4967,7 +4953,7 @@ Type *TypePointer::semantic(Loc loc, Scope *sc)
 
 d_uns64 TypePointer::size(Loc)
 {
-    return Target::ptrsize;
+    return target.ptrsize;
 }
 
 MATCH TypePointer::implicitConvTo(Type *to)
@@ -5111,7 +5097,7 @@ Type *TypeReference::semantic(Loc loc, Scope *sc)
 
 d_uns64 TypeReference::size(Loc)
 {
-    return Target::ptrsize;
+    return target.ptrsize;
 }
 
 Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
@@ -6474,12 +6460,12 @@ Type *TypeDelegate::addStorageClass(StorageClass stc)
 
 d_uns64 TypeDelegate::size(Loc)
 {
-    return Target::ptrsize * 2;
+    return target.ptrsize * 2;
 }
 
 unsigned TypeDelegate::alignsize()
 {
-    return Target::ptrsize;
+    return target.ptrsize;
 }
 
 MATCH TypeDelegate::implicitConvTo(Type *to)
@@ -8148,7 +8134,7 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc)
     /* Copy from the initializer symbol for larger symbols,
      * otherwise the literals expressed as code get excessively large.
      */
-    if (size(loc) > Target::ptrsize * 4U && !needsNested())
+    if (size(loc) > target.ptrsize * 4U && !needsNested())
         structinit->useStaticInit = true;
 
     structinit->type = this;
@@ -8401,7 +8387,7 @@ Type *TypeClass::semantic(Loc, Scope *sc)
 
 d_uns64 TypeClass::size(Loc)
 {
-    return Target::ptrsize;
+    return target.ptrsize;
 }
 
 Dsymbol *TypeClass::toDsymbol(Scope *)
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 6b5c297348a..4efeddd7af5 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -99,9 +99,6 @@ enum ENUMTY
 };
 typedef unsigned char TY;       // ENUMTY
 
-extern int Tsize_t;
-extern int Tptrdiff_t;
-
 #define SIZE_INVALID (~(d_uns64)0)   // error return from size() functions
 
 
@@ -193,7 +190,6 @@ public:
     static Type *tstring;               // immutable(char)[]
     static Type *twstring;              // immutable(wchar)[]
     static Type *tdstring;              // immutable(dchar)[]
-    static Type *tvalist;               // va_list alias
     static Type *terror;                // for error recovery
     static Type *tnull;                 // for null type
 
diff --git a/gcc/d/dmd/safe.c b/gcc/d/dmd/safe.c
index bf1bc31388e..08274af8bd4 100644
--- a/gcc/d/dmd/safe.c
+++ b/gcc/d/dmd/safe.c
@@ -58,8 +58,8 @@ bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg)
 
         if (v->type->hasPointers() && v->type->toBasetype()->ty != Tstruct)
         {
-            if ((ad->type->alignment() < (unsigned)Target::ptrsize ||
-                 (v->offset & (Target::ptrsize - 1))) &&
+            if ((ad->type->alignment() < target.ptrsize ||
+                 (v->offset & (target.ptrsize - 1))) &&
                 sc->func->setUnsafe())
             {
                 if (printmsg)
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index 3186db7e2a4..bfcb4b4db9c 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -1153,7 +1153,7 @@ public:
                         fs->key = new VarDeclaration(loc, Type::tsize_t, idkey, NULL);
                         fs->key->storage_class |= STCtemp;
                     }
-                    else if (fs->key->type->ty != Tsize_t)
+                    else if (fs->key->type->ty != Type::tsize_t->ty)
                     {
                         tmp_length = new CastExp(loc, tmp_length, fs->key->type);
                     }
@@ -1585,8 +1585,8 @@ public:
                         d_uns64 keysize = taa->index->size();
                         if (keysize == SIZE_INVALID)
                             goto Lerror2;
-                        assert(keysize < UINT64_MAX - Target::ptrsize);
-                        keysize = (keysize + (Target::ptrsize- 1)) & ~(Target::ptrsize - 1);
+                        assert(keysize < UINT64_MAX - target.ptrsize);
+                        keysize = (keysize + (target.ptrsize - 1)) & ~(target.ptrsize - 1);
                         // paint delegate argument to the type runtime expects
                         if (!fldeTy[i]->equals(flde->type))
                         {
@@ -3248,7 +3248,7 @@ public:
              *  try { body } finally { _d_criticalexit(critsec.ptr); }
              */
             Identifier *id = Identifier::generateId("__critsec");
-            Type *t = Type::tint8->sarrayOf(Target::ptrsize + Target::critsecsize());
+            Type *t = Type::tint8->sarrayOf(target.ptrsize + target.critsecsize());
             VarDeclaration *tmp = new VarDeclaration(ss->loc, t, id, NULL);
             tmp->storage_class |= STCtemp | STCgshared | STCstatic;
 
@@ -3829,7 +3829,7 @@ void semantic(Catch *c, Scope *sc)
         }
         else if (cd->isCPPclass())
         {
-            if (!Target::cppExceptions)
+            if (!target.cpp.exceptions)
             {
                 error(c->loc, "catching C++ class objects not supported for this target");
                 c->errors = true;
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index e8d4d6ad704..d76a9f89abd 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -24,55 +24,87 @@ class Type;
 class TypeTuple;
 struct OutBuffer;
 
+struct TargetC
+{
+    unsigned longsize;            // size of a C 'long' or 'unsigned long' type
+    unsigned long_doublesize;     // size of a C 'long double'
+    unsigned criticalSectionSize; // size of os critical section
+};
+
+struct TargetCPP
+{
+    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
+
+    const char *toMangle(Dsymbol *s);
+    const char *typeInfoMangle(ClassDeclaration *cd);
+    const char *typeMangle(Type *t);
+    Type *parameterType(Parameter *p);
+    bool fundamentalType(const Type *t, bool& isFundamental);
+};
+
+struct TargetObjC
+{
+    bool supported;     // set if compiler can interface with Objective-C
+};
+
 struct Target
 {
-    static int ptrsize;
-    static int realsize;             // size a real consumes in memory
-    static int realpad;              // 'padding' added to the CPU real size to bring it up to realsize
-    static int realalignsize;        // alignment for reals
-    static bool reverseCppOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order
-    static bool cppExceptions;       // set if catching C++ exceptions is supported
-    static int c_longsize;           // size of a C 'long' or 'unsigned long' type
-    static int c_long_doublesize;    // size of a C 'long double'
-    static int classinfosize;        // size of 'ClassInfo'
-    static unsigned long long maxStaticDataSize;  // maximum size of static data
+    // 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
+
+    // C ABI
+    TargetC c;
+
+    // C++ ABI
+    TargetCPP cpp;
+
+    // Objective-C ABI
+    TargetObjC objc;
 
     template <typename T>
     struct FPTypeProperties
     {
-        static real_t max;
-        static real_t min_normal;
-        static real_t nan;
-        static real_t snan;
-        static real_t infinity;
-        static real_t epsilon;
-
-        static d_int64 dig;
-        static d_int64 mant_dig;
-        static d_int64 max_exp;
-        static d_int64 min_exp;
-        static d_int64 max_10_exp;
-        static d_int64 min_10_exp;
+        real_t max;
+        real_t min_normal;
+        real_t nan;
+        real_t snan;
+        real_t infinity;
+        real_t epsilon;
+
+        d_int64 dig;
+        d_int64 mant_dig;
+        d_int64 max_exp;
+        d_int64 min_exp;
+        d_int64 max_10_exp;
+        d_int64 min_10_exp;
     };
 
-    typedef FPTypeProperties<float> FloatProperties;
-    typedef FPTypeProperties<double> DoubleProperties;
-    typedef FPTypeProperties<real_t> RealProperties;
+    FPTypeProperties<float> FloatProperties;
+    FPTypeProperties<double> DoubleProperties;
+    FPTypeProperties<real_t> RealProperties;
 
-    static void _init();
+private:
+    Type *tvalist;
+
+public:
+    void _init(const Param& params);
     // Type sizes and support.
-    static unsigned alignsize(Type* type);
-    static unsigned fieldalign(Type* type);
-    static unsigned critsecsize();
-    static Type *va_listType();  // get type of va_list
-    static int isVectorTypeSupported(int sz, Type *type);
-    static bool isVectorOpSupported(Type *type, TOK op, Type *t2 = NULL);
+    unsigned alignsize(Type *type);
+    unsigned fieldalign(Type *type);
+    unsigned critsecsize();
+    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);
     // ABI and backend.
-    static const char *toCppMangle(Dsymbol *s);
-    static const char *cppTypeInfoMangle(ClassDeclaration *cd);
-    static const char *cppTypeMangle(Type *t);
-    static Type *cppParameterType(Parameter *p);
-    static bool cppFundamentalType(const Type *t, bool& isFundamental);
-    static LINK systemLinkage();
-    static TypeTuple *toArgTypes(Type *t);
+    LINK systemLinkage();
+    TypeTuple *toArgTypes(Type *t);
 };
+
+extern Target target;
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index fdeb70030cb..1c5d669abf8 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -1223,7 +1223,7 @@ layout_classinfo_interfaces (ClassDeclaration *decl)
 
 	      field = create_field_decl (vtbltype, NULL, 1, 1);
 	      insert_aggregate_field (type, field, offset);
-	      structsize += id->vtbl.length * Target::ptrsize;
+	      structsize += id->vtbl.length * target.ptrsize;
 	    }
 	}
     }
@@ -1247,7 +1247,7 @@ layout_classinfo_interfaces (ClassDeclaration *decl)
 
 	      tree field = create_field_decl (vtbltype, NULL, 1, 1);
 	      insert_aggregate_field (type, field, offset);
-	      structsize += id->vtbl.length * Target::ptrsize;
+	      structsize += id->vtbl.length * target.ptrsize;
 	    }
 	}
     }
@@ -1415,7 +1415,7 @@ layout_cpp_typeinfo (ClassDeclaration *cd)
 
   /* Let C++ do the RTTI generation, and just reference the symbol as
      extern, knowing the underlying type is not required.  */
-  const char *ident = Target::cppTypeInfoMangle (cd);
+  const char *ident = target.cpp.typeInfoMangle (cd);
   tree typeinfo = declare_extern_var (get_identifier (ident),
 				      unknown_type_node);
   TREE_READONLY (typeinfo) = 1;
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index e8073b860fa..0fda81c31e7 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -49,10 +49,11 @@ along with GCC; see the file COPYING3.  If not see
 bool
 valist_array_p (Type *type)
 {
-  if (Type::tvalist->ty == Tsarray)
+  Type *tvalist = target.va_listType (Loc (), NULL);
+  if (tvalist->ty == Tsarray)
     {
       Type *tb = type->toBasetype ();
-      if (same_type_p (tb, Type::tvalist))
+      if (same_type_p (tb, tvalist))
 	return true;
     }
 
@@ -423,7 +424,7 @@ layout_aggregate_type (AggregateDeclaration *decl, tree type,
 	    {
 	      tree field = create_field_decl (ptr_type_node, "__monitor", 1,
 					      inherited_p);
-	      insert_aggregate_field (type, field, Target::ptrsize);
+	      insert_aggregate_field (type, field, target.ptrsize);
 	    }
 	}
 
