aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2018-07-31 21:19:13 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2018-07-31 21:19:13 +0000
commitfa6fd7b7afece6e0cfe197c9419ea3346d3c60b2 (patch)
treef227c6802b9656b6bc7d3b3f090e9b9d78f1bb4b /gcc/ada
parente540ccc0e281a6e30c14e55b39334db27e55b3bf (diff)
downloadgcc-fa6fd7b7afece6e0cfe197c9419ea3346d3c60b2.zip
gcc-fa6fd7b7afece6e0cfe197c9419ea3346d3c60b2.tar.gz
gcc-fa6fd7b7afece6e0cfe197c9419ea3346d3c60b2.tar.bz2
Introduce instance discriminators
With -gnateS, the Ada compiler sets itself up to output discriminators for different instantiations of generics, but the middle and back ends have lacked support for that. This patch introduces the missing bits, translating the GNAT-internal representation of the per-file instance map to an instance_table that maps decls to instance discriminators. From: Alexandre Oliva <oliva@adacore.com>, Olivier Hainque <hainque@adacore.com> for gcc/ChangeLog * debug.h (decl_to_instance_map_t): New type. (decl_to_instance_map): Declare. (maybe_create_decl_to_instance_map): New inline function. * final.c (bb_discriminator, last_bb_discriminator): New statics, to track basic block discriminators. (final_start_function_1): Initialize them. (final_scan_insn_1): On NOTE_INSN_BASIC_BLOCK, track bb_discriminator. (decl_to_instance_map): New variable. (map_decl_to_instance, maybe_set_discriminator): New functions. (notice_source_line): Set discriminator. for gcc/ada/ChangeLog * trans.c: Include debug.h. (file_map): New static variable. (gigi): Set it. Create decl_to_instance_map when needed. (Subprogram_Body_to_gnu): Pass gnu_subprog_decl to... (Sloc_to_locus): ... this. Add decl parm, map it to instance. * gigi.h (Sloc_to_locus): Adjust declaration. for gcc/testsuite/ChangeLog * gnat.dg/dinst.adb: New. * gnat.dg/dinst_pkg.ads, gnat.dg/dinst_pkg.adb: New. Co-Authored-By: Olivier Hainque <hainque@adacore.com> From-SVN: r263182
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog10
-rw-r--r--gcc/ada/gcc-interface/gigi.h2
-rw-r--r--gcc/ada/gcc-interface/trans.c29
3 files changed, 35 insertions, 6 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c6f1911..8b1de0c 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,13 @@
+2018-07-31 Alexandre Oliva <oliva@adacore.com>
+ Olivier Hainque <hainque@adacore.com>
+
+ * trans.c: Include debug.h.
+ (file_map): New static variable.
+ (gigi): Set it. Create decl_to_instance_map when needed.
+ (Subprogram_Body_to_gnu): Pass gnu_subprog_decl to...
+ (Sloc_to_locus): ... this. Add decl parm, map it to instance.
+ * gigi.h (Sloc_to_locus): Adjust declaration.
+
2018-07-31 Arnaud Charlet <charlet@adacore.com>
* clean.adb, gnatchop.adb, gnatfind.adb, gnatls.adb,
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index a75cb90..b890195 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -285,7 +285,7 @@ extern void process_type (Entity_Id gnat_entity);
location and false if it doesn't. If CLEAR_COLUMN is true, set the column
information to 0. */
extern bool Sloc_to_locus (Source_Ptr Sloc, location_t *locus,
- bool clear_column = false);
+ bool clear_column = false, const_tree decl = 0);
/* Post an error message. MSG is the error message, properly annotated.
NODE is the node at which to post the error and the node to use for the
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 31e098a..0371d00 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -41,6 +41,7 @@
#include "stmt.h"
#include "varasm.h"
#include "output.h"
+#include "debug.h"
#include "libfuncs.h" /* For set_stack_check_libfunc. */
#include "tree-iterator.h"
#include "gimplify.h"
@@ -255,6 +256,12 @@ static tree create_init_temporary (const char *, tree, tree *, Node_Id);
static const char *extract_encoding (const char *) ATTRIBUTE_UNUSED;
static const char *decode_name (const char *) ATTRIBUTE_UNUSED;
+/* This makes gigi's file_info_ptr visible in this translation unit,
+ so that Sloc_to_locus can look it up when deciding whether to map
+ decls to instances. */
+
+static struct File_Info_Type *file_map;
+
/* This is the main program of the back-end. It sets up all the table
structures and then generates code. */
@@ -300,6 +307,12 @@ gigi (Node_Id gnat_root,
type_annotate_only = (gigi_operating_mode == 1);
+ if (Generate_SCO_Instance_Table != 0)
+ {
+ file_map = file_info_ptr;
+ maybe_create_decl_to_instance_map (number_file);
+ }
+
for (i = 0; i < number_file; i++)
{
/* Use the identifier table to make a permanent copy of the filename as
@@ -701,6 +714,7 @@ gigi (Node_Id gnat_root,
}
/* Destroy ourselves. */
+ file_map = NULL;
destroy_gnat_decl ();
destroy_gnat_utils ();
@@ -3771,7 +3785,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
}
/* Set the line number in the decl to correspond to that of the body. */
- if (!Sloc_to_locus (Sloc (gnat_node), &locus))
+ if (!Sloc_to_locus (Sloc (gnat_node), &locus, false, gnu_subprog_decl))
locus = input_location;
DECL_SOURCE_LOCATION (gnu_subprog_decl) = locus;
@@ -9970,12 +9984,14 @@ maybe_implicit_deref (tree exp)
return exp;
}
-/* Convert SLOC into LOCUS. Return true if SLOC corresponds to a source code
- location and false if it doesn't. If CLEAR_COLUMN is true, set the column
- information to 0. */
+/* Convert SLOC into LOCUS. Return true if SLOC corresponds to a
+ source code location and false if it doesn't. If CLEAR_COLUMN is
+ true, set the column information to 0. If DECL is given and SLOC
+ refers to a File with an instance, map DECL to that instance. */
bool
-Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column)
+Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column,
+ const_tree decl)
{
if (Sloc == No_Location)
return false;
@@ -9999,6 +10015,9 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column)
*locus
= linemap_position_for_line_and_column (line_table, map, line, column);
+ if (file_map && file_map[file - 1].Instance)
+ decl_to_instance_map->put (decl, file_map[file - 1].Instance);
+
return true;
}