From 06339ba74892b455ad2d2bc71048cea16b4e45a9 Mon Sep 17 00:00:00 2001
From: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri, 26 May 2017 23:06:39 +0200
Subject: [PATCH 06/14] Add patches for D language support in GCC proper.

This patch adds D language support to GCC itself.

---
gcc/ChangeLog

	* config/powerpcspe/powerpcspe.c (rs6000_output_function_epilogue):
	Support GNU D by using 0 as the language type.
	* config/rs6000/rs6000.c (rs6000_output_function_epilogue):
	Support GNU D by using 0 as the language type.
	* dwarf2out.c (is_dlang): New function.
	(gen_compile_unit_die): Use DW_LANG_D for D.
	(declare_in_namespace): Return module die for D, instead of adding
	extra declarations into the namespace.
	(gen_namespace_die): Generate DW_TAG_module for D.
	(gen_decl_die, dwarf2out_decl): Handle CONST_DECLSs for D.
	(prune_unused_types_walk_local_classes): Handle
	DW_tag_interface_type.
	(prune_unused_types_walk): Handle DW_tag_interface_type same as
	other kinds of aggregates.
	* gcc.c (default_compilers): Add entries for ".d", ".dd" and ".di".

gcc/po/ChangeLog:

        * EXCLUDES: Add sources from d/dfrontend.
---
 gcc/config/powerpcspe/powerpcspe.c |  5 ++--
 gcc/config/rs6000/rs6000.c         |  5 ++--
 gcc/dwarf2out.c                    | 23 +++++++++++++----
 gcc/gcc.c                          |  1 +
 gcc/po/EXCLUDES                    | 40 ++++++++++++++++++++++++++++++
 5 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/gcc/config/powerpcspe/powerpcspe.c b/gcc/config/powerpcspe/powerpcspe.c
index dea1eab1188..8b157174473 100644
--- a/gcc/config/powerpcspe/powerpcspe.c
+++ b/gcc/config/powerpcspe/powerpcspe.c
@@ -32026,11 +32026,12 @@ rs6000_output_function_epilogue (FILE *file)
 	 use language_string.
 	 C is 0.  Fortran is 1.  Pascal is 2.  Ada is 3.  C++ is 9.
 	 Java is 13.  Objective-C is 14.  Objective-C++ isn't assigned
-	 a number, so for now use 9.  LTO, Go and JIT aren't assigned numbers
-	 either, so for now use 0.  */
+	 a number, so for now use 9.  LTO, Go, D and JIT aren't assigned
+	 numbers either, so for now use 0.  */
       if (lang_GNU_C ()
 	  || ! strcmp (language_string, "GNU GIMPLE")
 	  || ! strcmp (language_string, "GNU Go")
+	  || ! strcmp (language_string, "GNU D")
 	  || ! strcmp (language_string, "libgccjit"))
 	i = 0;
       else if (! strcmp (language_string, "GNU F77")
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a36e6140ecb..97ca2dac289 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -28405,11 +28405,12 @@ rs6000_output_function_epilogue (FILE *file)
 	 use language_string.
 	 C is 0.  Fortran is 1.  Pascal is 2.  Ada is 3.  C++ is 9.
 	 Java is 13.  Objective-C is 14.  Objective-C++ isn't assigned
-	 a number, so for now use 9.  LTO, Go and JIT aren't assigned numbers
-	 either, so for now use 0.  */
+	 a number, so for now use 9.  LTO, Go, D, and JIT aren't assigned
+	 numbers either, so for now use 0.  */
       if (lang_GNU_C ()
 	  || ! strcmp (language_string, "GNU GIMPLE")
 	  || ! strcmp (language_string, "GNU Go")
+	  || ! strcmp (language_string, "GNU D")
 	  || ! strcmp (language_string, "libgccjit"))
 	i = 0;
       else if (! strcmp (language_string, "GNU F77")
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 48c50378622..47877faebd7 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5521,6 +5521,16 @@ is_ada (void)
   return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
 }
 
+/* Return TRUE if the language is D.  */
+
+static inline bool
+is_dlang (void)
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_D;
+}
+
 /* Remove the specified attribute if present.  Return TRUE if removal
    was successful.  */
 
@@ -24550,6 +24560,8 @@ gen_compile_unit_die (const char *filename)
 	language = DW_LANG_ObjC;
       else if (strcmp (language_string, "GNU Objective-C++") == 0)
 	language = DW_LANG_ObjC_plus_plus;
+      else if (strcmp (language_string, "GNU D") == 0)
+	language = DW_LANG_D;
       else if (dwarf_version >= 5 || !dwarf_strict)
 	{
 	  if (strcmp (language_string, "GNU Go") == 0)
@@ -26150,7 +26162,7 @@ declare_in_namespace (tree thing, dw_die_ref context_die)
 
   if (ns_context != context_die)
     {
-      if (is_fortran ())
+      if (is_fortran () || is_dlang ())
 	return ns_context;
       if (DECL_P (thing))
 	gen_decl_die (thing, NULL, NULL, ns_context);
@@ -26173,7 +26185,7 @@ gen_namespace_die (tree decl, dw_die_ref context_die)
     {
       /* Output a real namespace or module.  */
       context_die = setup_namespace_context (decl, comp_unit_die ());
-      namespace_die = new_die (is_fortran ()
+      namespace_die = new_die (is_fortran () || is_dlang ()
 			       ? DW_TAG_module : DW_TAG_namespace,
 			       context_die, decl);
       /* For Fortran modules defined in different CU don't add src coords.  */
@@ -26239,7 +26251,7 @@ gen_decl_die (tree decl, tree origin, struct vlr_context *ctx,
       break;
 
     case CONST_DECL:
-      if (!is_fortran () && !is_ada ())
+      if (!is_fortran () && !is_ada () && !is_dlang ())
 	{
 	  /* The individual enumerators of an enum type get output when we output
 	     the Dwarf representation of the relevant enum type itself.  */
@@ -26839,7 +26851,7 @@ dwarf2out_decl (tree decl)
     case CONST_DECL:
       if (debug_info_level <= DINFO_LEVEL_TERSE)
 	return;
-      if (!is_fortran () && !is_ada ())
+      if (!is_fortran () && !is_ada () && !is_dlang ())
 	return;
       if (TREE_STATIC (decl) && decl_function_context (decl))
 	context_die = lookup_decl_die (DECL_CONTEXT (decl));
@@ -29240,6 +29252,7 @@ prune_unused_types_walk_local_classes (dw_die_ref die)
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
     case DW_TAG_class_type:
+    case DW_TAG_interface_type:
       break;
 
     case DW_TAG_subprogram:
@@ -29273,6 +29286,7 @@ prune_unused_types_walk (dw_die_ref die)
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
     case DW_TAG_class_type:
+    case DW_TAG_interface_type:
       if (die->die_perennial_p)
 	break;
 
@@ -29299,7 +29313,6 @@ prune_unused_types_walk (dw_die_ref die)
     case DW_TAG_volatile_type:
     case DW_TAG_typedef:
     case DW_TAG_array_type:
-    case DW_TAG_interface_type:
     case DW_TAG_friend:
     case DW_TAG_enumeration_type:
     case DW_TAG_subroutine_type:
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 8be82eaa04f..c9c6d304f82 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1305,6 +1305,7 @@ static const struct compiler default_compilers[] =
   {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0},
   {".r", "#Ratfor", 0, 0, 0},
   {".go", "#Go", 0, 1, 0},
+  {".d", "#D", 0, 1, 0}, {".dd", "#D", 0, 1, 0}, {".di", "#D", 0, 1, 0},
   /* Next come the entries for C.  */
   {".c", "@c", 0, 0, 1},
   {"@c",
diff --git a/gcc/po/EXCLUDES b/gcc/po/EXCLUDES
index 50274233cf0..60638b756a0 100644
--- a/gcc/po/EXCLUDES
+++ b/gcc/po/EXCLUDES
@@ -53,3 +53,43 @@ genrecog.c
 gensupport.c
 gensupport.h
 read-md.c
+
+#   These files are part of the front end to D, and have no i18n support.
+d/dfrontend/arrayop.c
+d/dfrontend/attrib.c
+d/dfrontend/canthrow.c
+d/dfrontend/cond.c
+d/dfrontend/constfold.c
+d/dfrontend/cppmangle.c
+d/dfrontend/ctfeexpr.c
+d/dfrontend/dcast.c
+d/dfrontend/dclass.c
+d/dfrontend/declaration.c
+d/dfrontend/denum.c
+d/dfrontend/dimport.c
+d/dfrontend/dinterpret.c
+d/dfrontend/dmangle.c
+d/dfrontend/dmodule.c
+d/dfrontend/doc.c
+d/dfrontend/dscope.c
+d/dfrontend/dstruct.c
+d/dfrontend/dsymbol.c
+d/dfrontend/dtemplate.c
+d/dfrontend/dversion.c
+d/dfrontend/expression.c
+d/dfrontend/func.c
+d/dfrontend/init.c
+d/dfrontend/inline.c
+d/dfrontend/lexer.c
+d/dfrontend/mtype.c
+d/dfrontend/nogc.c
+d/dfrontend/nspace.c
+d/dfrontend/objc.c
+d/dfrontend/opover.c
+d/dfrontend/optimize.c
+d/dfrontend/parse.c
+d/dfrontend/sideeffect.c
+d/dfrontend/statement.c
+d/dfrontend/statementsem.c
+d/dfrontend/staticassert.c
+d/dfrontend/traits.c
-- 
2.17.1

