mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 18:20:51 +08:00
Mapped location support
Mapped location support * back_end.adb (Call_Back_End): Pass information about source files instead of units to gigi. * gigi.h (struct File_Info_Type): New. (gigi): Rename and change type of number_units parameter, change type of file_info_ptr parameter. * trans.c (number_files): New global variable. (gigi): Rename and change type of number_units parameter, change type of file_info_ptr parameter. If mapped location support is enabled, create the isomorphic mapping between source files and line maps. (Sloc_to_locus): If mapped location support is enabled, translate source location into mapped location. (annotate_with_node): Rename into set_expr_location_from_node. Call set_expr_location instead of annotate_with_locus. (Pragma_to_gnu): Adjust for above change. (Loop_Statement_to_gnu): Likewise. (call_to_gnu): Likewise. (Handled_Sequence_Of_Statements_to_gnu): Likewise. (gnat_to_gnu): Likewise. (add_stmt_with_node): Likewise. (add_cleanup): Likewise. * utils.c (gnat_init_decl_processing): Do not set input_line. From-SVN: r128839
This commit is contained in:
parent
3c1eb9eb6c
commit
c304878307
@ -1,3 +1,29 @@
|
||||
2007-09-27 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
Mapped location support
|
||||
* back_end.adb (Call_Back_End): Pass information about source
|
||||
files instead of units to gigi.
|
||||
* gigi.h (struct File_Info_Type): New.
|
||||
(gigi): Rename and change type of number_units parameter, change
|
||||
type of file_info_ptr parameter.
|
||||
* trans.c (number_files): New global variable.
|
||||
(gigi): Rename and change type of number_units parameter, change
|
||||
type of file_info_ptr parameter.
|
||||
If mapped location support is enabled, create the isomorphic mapping
|
||||
between source files and line maps.
|
||||
(Sloc_to_locus): If mapped location support is enabled, translate
|
||||
source location into mapped location.
|
||||
(annotate_with_node): Rename into set_expr_location_from_node.
|
||||
Call set_expr_location instead of annotate_with_locus.
|
||||
(Pragma_to_gnu): Adjust for above change.
|
||||
(Loop_Statement_to_gnu): Likewise.
|
||||
(call_to_gnu): Likewise.
|
||||
(Handled_Sequence_Of_Statements_to_gnu): Likewise.
|
||||
(gnat_to_gnu): Likewise.
|
||||
(add_stmt_with_node): Likewise.
|
||||
(add_cleanup): Likewise.
|
||||
* utils.c (gnat_init_decl_processing): Do not set input_line.
|
||||
|
||||
2007-09-26 Hristian Kirtchev <kirtchev@adacore.com>
|
||||
|
||||
* sem_ch8.adb (Analyze_Use_Type): Code cleanup.
|
||||
|
@ -48,19 +48,16 @@ package body Back_End is
|
||||
|
||||
procedure Call_Back_End (Mode : Back_End_Mode_Type) is
|
||||
|
||||
-- The File_Record type has a lot of components that are meaningless
|
||||
-- to the back end, so a new record is created here to contain the
|
||||
-- needed information for each file.
|
||||
-- The Source_File_Record type has a lot of components that are
|
||||
-- meaningless to the back end, so a new record type is created
|
||||
-- here to contain the needed information for each file.
|
||||
|
||||
type Needed_File_Info_Type is record
|
||||
type File_Info_Type is record
|
||||
File_Name : File_Name_Type;
|
||||
First_Sloc : Source_Ptr;
|
||||
Last_Sloc : Source_Ptr;
|
||||
Num_Source_Lines : Nat;
|
||||
end record;
|
||||
|
||||
File_Info_Array :
|
||||
array (Main_Unit .. Last_Unit) of Needed_File_Info_Type;
|
||||
File_Info_Array : array (1 .. Last_Source_File) of File_Info_Type;
|
||||
|
||||
procedure gigi (
|
||||
gnat_root : Int;
|
||||
@ -76,7 +73,7 @@ package body Back_End is
|
||||
strings_ptr : Address;
|
||||
string_chars_ptr : Address;
|
||||
list_headers_ptr : Address;
|
||||
number_units : Int;
|
||||
number_file : Nat;
|
||||
|
||||
file_info_ptr : Address;
|
||||
gigi_standard_integer : Entity_Id;
|
||||
@ -86,8 +83,6 @@ package body Back_End is
|
||||
|
||||
pragma Import (C, gigi);
|
||||
|
||||
S : Source_File_Index;
|
||||
|
||||
begin
|
||||
-- Skip call if in -gnatdH mode
|
||||
|
||||
@ -95,12 +90,9 @@ package body Back_End is
|
||||
return;
|
||||
end if;
|
||||
|
||||
for J in Main_Unit .. Last_Unit loop
|
||||
S := Source_Index (J);
|
||||
File_Info_Array (J).File_Name := File_Name (S);
|
||||
File_Info_Array (J).First_Sloc := Source_Text (S)'First;
|
||||
File_Info_Array (J).Last_Sloc := Source_Text (S)'Last;
|
||||
File_Info_Array (J).Num_Source_Lines := Num_Source_Lines (S);
|
||||
for I in 1 .. Last_Source_File loop
|
||||
File_Info_Array (I).File_Name := Full_Debug_Name (I);
|
||||
File_Info_Array (I).Num_Source_Lines := Num_Source_Lines (I);
|
||||
end loop;
|
||||
|
||||
gigi (
|
||||
@ -117,7 +109,7 @@ package body Back_End is
|
||||
strings_ptr => Strings_Address,
|
||||
string_chars_ptr => String_Chars_Address,
|
||||
list_headers_ptr => Lists_Address,
|
||||
number_units => Num_Units,
|
||||
number_file => Num_Source_Files,
|
||||
|
||||
file_info_ptr => File_Info_Array'Address,
|
||||
gigi_standard_integer => Standard_Integer,
|
||||
|
@ -192,6 +192,13 @@ extern bool type_annotate_only;
|
||||
/* Current file name without path */
|
||||
extern const char *ref_filename;
|
||||
|
||||
/* This structure must be kept synchronized with Call_Back_End. */
|
||||
struct File_Info_Type
|
||||
{
|
||||
File_Name_Type File_Name;
|
||||
Nat Num_Source_Lines;
|
||||
};
|
||||
|
||||
/* This is the main program of the back-end. It sets up all the table
|
||||
structures and then generates code.
|
||||
|
||||
@ -204,8 +211,8 @@ extern void gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
|
||||
struct String_Entry *strings_ptr,
|
||||
Char_Code *strings_chars_ptr,
|
||||
struct List_Header *list_headers_ptr,
|
||||
Int number_units ATTRIBUTE_UNUSED,
|
||||
char *file_info_ptr ATTRIBUTE_UNUSED,
|
||||
Nat number_file,
|
||||
struct File_Info_Type *file_info_ptr ATTRIBUTE_UNUSED,
|
||||
Entity_Id standard_integer,
|
||||
Entity_Id standard_long_long_float,
|
||||
Entity_Id standard_exception_type,
|
||||
@ -229,11 +236,9 @@ extern int gnat_gimplify_expr (tree *expr_p, tree *pre_p,
|
||||
make a GCC type for GNAT_ENTITY and set up the correspondence. */
|
||||
extern void process_type (Entity_Id gnat_entity);
|
||||
|
||||
/* Convert Sloc into *LOCUS (a location_t). Return true if this Sloc
|
||||
corresponds to a source code location and false if it doesn't. In the
|
||||
latter case, we don't update *LOCUS. We also set the Gigi global variable
|
||||
REF_FILENAME to the reference file name as given by sinput (i.e no
|
||||
directory). */
|
||||
/* Convert SLOC into LOCUS. Return true if SLOC corresponds to a source code
|
||||
location and false if it doesn't. In the former case, set the Gigi global
|
||||
variable REF_FILENAME to the simple debug file name as given by sinput. */
|
||||
extern bool Sloc_to_locus (Source_Ptr Sloc, location_t *locus);
|
||||
|
||||
/* Post an error message. MSG is the error message, properly annotated.
|
||||
|
111
gcc/ada/trans.c
111
gcc/ada/trans.c
@ -68,8 +68,11 @@
|
||||
#define TARGET_ABI_OPEN_VMS 0
|
||||
#endif
|
||||
|
||||
extern char *__gnat_to_canonical_file_spec (char *);
|
||||
|
||||
int max_gnat_nodes;
|
||||
int number_names;
|
||||
int number_files;
|
||||
struct Node *Nodes_Ptr;
|
||||
Node_Id *Next_Node_Ptr;
|
||||
Node_Id *Prev_Node_Ptr;
|
||||
@ -205,7 +208,7 @@ static tree pos_to_constructor (Node_Id, tree, Entity_Id);
|
||||
static tree maybe_implicit_deref (tree);
|
||||
static tree gnat_stabilize_reference (tree, bool);
|
||||
static tree gnat_stabilize_reference_1 (tree, bool);
|
||||
static void annotate_with_node (tree, Node_Id);
|
||||
static void set_expr_location_from_node (tree, Node_Id);
|
||||
static int lvalue_required_p (Node_Id, tree, int);
|
||||
|
||||
/* This is the main program of the back-end. It sets up all the table
|
||||
@ -216,17 +219,19 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
|
||||
struct Node *nodes_ptr, Node_Id *next_node_ptr, Node_Id *prev_node_ptr,
|
||||
struct Elist_Header *elists_ptr, struct Elmt_Item *elmts_ptr,
|
||||
struct String_Entry *strings_ptr, Char_Code *string_chars_ptr,
|
||||
struct List_Header *list_headers_ptr, Int number_units ATTRIBUTE_UNUSED,
|
||||
char *file_info_ptr ATTRIBUTE_UNUSED, Entity_Id standard_integer,
|
||||
Entity_Id standard_long_long_float, Entity_Id standard_exception_type,
|
||||
Int gigi_operating_mode)
|
||||
struct List_Header *list_headers_ptr, Nat number_file,
|
||||
struct File_Info_Type *file_info_ptr ATTRIBUTE_UNUSED,
|
||||
Entity_Id standard_integer, Entity_Id standard_long_long_float,
|
||||
Entity_Id standard_exception_type, Int gigi_operating_mode)
|
||||
{
|
||||
tree gnu_standard_long_long_float;
|
||||
tree gnu_standard_exception_type;
|
||||
struct elab_info *info;
|
||||
int i ATTRIBUTE_UNUSED;
|
||||
|
||||
max_gnat_nodes = max_gnat_node;
|
||||
number_names = number_name;
|
||||
number_files = number_file;
|
||||
Nodes_Ptr = nodes_ptr;
|
||||
Next_Node_Ptr = next_node_ptr;
|
||||
Prev_Node_Ptr = prev_node_ptr;
|
||||
@ -238,6 +243,32 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
|
||||
|
||||
type_annotate_only = (gigi_operating_mode == 1);
|
||||
|
||||
#ifdef USE_MAPPED_LOCATION
|
||||
for (i = 0; i < number_files; i++)
|
||||
{
|
||||
/* Use the identifier table to make a permanent copy of the filename as
|
||||
the name table gets reallocated after Gigi returns but before all the
|
||||
debugging information is output. The __gnat_to_canonical_file_spec
|
||||
call translates filenames from pragmas Source_Reference that contain
|
||||
host style syntax not understood by gdb. */
|
||||
const char *filename
|
||||
= IDENTIFIER_POINTER
|
||||
(get_identifier
|
||||
(__gnat_to_canonical_file_spec
|
||||
(Get_Name_String (file_info_ptr[i].File_Name))));
|
||||
|
||||
/* We rely on the order isomorphism between files and line maps. */
|
||||
gcc_assert ((int) line_table->used == i);
|
||||
|
||||
/* We create the line map for a source file at once, with a fixed number
|
||||
of columns chosen to avoid jumping over the next power of 2. */
|
||||
linemap_add (line_table, LC_ENTER, 0, filename, 1);
|
||||
linemap_line_start (line_table, file_info_ptr[i].Num_Source_Lines, 252);
|
||||
linemap_position_for_column (line_table, 252 - 1);
|
||||
linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
init_gnat_to_gnu ();
|
||||
gnat_compute_largest_alignment ();
|
||||
init_dummy_type ();
|
||||
@ -699,7 +730,7 @@ Pragma_to_gnu (Node_Id gnat_node)
|
||||
gnu_expr, NULL_TREE),
|
||||
NULL_TREE);
|
||||
ASM_VOLATILE_P (gnu_expr) = 1;
|
||||
annotate_with_node (gnu_expr, gnat_node);
|
||||
set_expr_location_from_node (gnu_expr, gnat_node);
|
||||
append_to_statement_list (gnu_expr, &gnu_result);
|
||||
}
|
||||
break;
|
||||
@ -1517,7 +1548,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
|
||||
TREE_TYPE (gnu_loop_stmt) = void_type_node;
|
||||
TREE_SIDE_EFFECTS (gnu_loop_stmt) = 1;
|
||||
LOOP_STMT_LABEL (gnu_loop_stmt) = create_artificial_label ();
|
||||
annotate_with_node (gnu_loop_stmt, gnat_node);
|
||||
set_expr_location_from_node (gnu_loop_stmt, gnat_node);
|
||||
|
||||
/* Save the end label of this LOOP_STMT in a stack so that the corresponding
|
||||
N_Exit_Statement can find it. */
|
||||
@ -1562,7 +1593,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
|
||||
build_binary_op (LE_EXPR, integer_type_node,
|
||||
gnu_low, gnu_high),
|
||||
NULL_TREE, alloc_stmt_list ());
|
||||
annotate_with_node (gnu_cond_expr, gnat_loop_spec);
|
||||
set_expr_location_from_node (gnu_cond_expr, gnat_loop_spec);
|
||||
}
|
||||
|
||||
/* Open a new nesting level that will surround the loop to declare the
|
||||
@ -1597,7 +1628,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
|
||||
gnu_loop_var,
|
||||
convert (TREE_TYPE (gnu_loop_var),
|
||||
integer_one_node));
|
||||
annotate_with_node (LOOP_STMT_UPDATE (gnu_loop_stmt),
|
||||
set_expr_location_from_node (LOOP_STMT_UPDATE (gnu_loop_stmt),
|
||||
gnat_iter_scheme);
|
||||
}
|
||||
|
||||
@ -2091,7 +2122,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
|
||||
/* Set up to move the copy back to the original. */
|
||||
gnu_temp = build_binary_op (MODIFY_EXPR, NULL_TREE,
|
||||
gnu_copy, gnu_actual);
|
||||
annotate_with_node (gnu_temp, gnat_actual);
|
||||
set_expr_location_from_node (gnu_temp, gnat_actual);
|
||||
append_to_statement_list (gnu_temp, &gnu_after_list);
|
||||
|
||||
/* Account for next statement just below. */
|
||||
@ -2453,7 +2484,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
|
||||
|
||||
gnu_result = build_binary_op (MODIFY_EXPR, NULL_TREE,
|
||||
gnu_actual, gnu_result);
|
||||
annotate_with_node (gnu_result, gnat_actual);
|
||||
set_expr_location_from_node (gnu_result, gnat_actual);
|
||||
append_to_statement_list (gnu_result, &gnu_before_list);
|
||||
scalar_return_list = TREE_CHAIN (scalar_return_list);
|
||||
gnu_name_list = TREE_CHAIN (gnu_name_list);
|
||||
@ -2461,7 +2492,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
|
||||
}
|
||||
else
|
||||
{
|
||||
annotate_with_node (gnu_subprog_call, gnat_node);
|
||||
set_expr_location_from_node (gnu_subprog_call, gnat_node);
|
||||
append_to_statement_list (gnu_subprog_call, &gnu_before_list);
|
||||
}
|
||||
|
||||
@ -2611,7 +2642,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
|
||||
defer abortion. */
|
||||
gnu_expr = build_call_1_expr (raise_nodefer_decl,
|
||||
TREE_VALUE (gnu_except_ptr_stack));
|
||||
annotate_with_node (gnu_expr, gnat_node);
|
||||
set_expr_location_from_node (gnu_expr, gnat_node);
|
||||
|
||||
if (gnu_else_ptr)
|
||||
*gnu_else_ptr = gnu_expr;
|
||||
@ -3977,7 +4008,7 @@ gnat_to_gnu (Node_Id gnat_node)
|
||||
COND_EXPR_THEN (gnu_expr)
|
||||
= build_stmt_group (Then_Statements (gnat_temp), false);
|
||||
TREE_SIDE_EFFECTS (gnu_expr) = 1;
|
||||
annotate_with_node (gnu_expr, gnat_temp);
|
||||
set_expr_location_from_node (gnu_expr, gnat_temp);
|
||||
*gnu_else_ptr = gnu_expr;
|
||||
gnu_else_ptr = &COND_EXPR_ELSE (gnu_expr);
|
||||
}
|
||||
@ -4617,7 +4648,7 @@ gnat_to_gnu (Node_Id gnat_node)
|
||||
is one. */
|
||||
if (TREE_CODE (gnu_result_type) == VOID_TYPE)
|
||||
{
|
||||
annotate_with_node (gnu_result, gnat_node);
|
||||
set_expr_location_from_node (gnu_result, gnat_node);
|
||||
|
||||
if (Present (Condition (gnat_node)))
|
||||
gnu_result = build3 (COND_EXPR, void_type_node,
|
||||
@ -4708,7 +4739,7 @@ gnat_to_gnu (Node_Id gnat_node)
|
||||
no result if we tried to build a CALL_EXPR node to a procedure with
|
||||
no side-effects and optimization is enabled. */
|
||||
if (gnu_result && EXPR_P (gnu_result) && !REFERENCE_CLASS_P (gnu_result))
|
||||
annotate_with_node (gnu_result, gnat_node);
|
||||
set_expr_location_from_node (gnu_result, gnat_node);
|
||||
|
||||
/* If we're supposed to return something of void_type, it means we have
|
||||
something we're elaborating for effect, so just return. */
|
||||
@ -4895,7 +4926,7 @@ void
|
||||
add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node)
|
||||
{
|
||||
if (Present (gnat_node))
|
||||
annotate_with_node (gnu_stmt, gnat_node);
|
||||
set_expr_location_from_node (gnu_stmt, gnat_node);
|
||||
add_stmt (gnu_stmt);
|
||||
}
|
||||
|
||||
@ -5011,7 +5042,7 @@ static void
|
||||
add_cleanup (tree gnu_cleanup, Node_Id gnat_node)
|
||||
{
|
||||
if (Present (gnat_node))
|
||||
annotate_with_node (gnu_cleanup, gnat_node);
|
||||
set_expr_location_from_node (gnu_cleanup, gnat_node);
|
||||
append_to_statement_list (gnu_cleanup, ¤t_stmt_group->cleanups);
|
||||
}
|
||||
|
||||
@ -6518,21 +6549,37 @@ gnat_stabilize_reference_1 (tree e, bool force)
|
||||
return result;
|
||||
}
|
||||
|
||||
extern char *__gnat_to_canonical_file_spec (char *);
|
||||
|
||||
/* Convert Sloc into *LOCUS (a location_t). Return true if this Sloc
|
||||
corresponds to a source code location and false if it doesn't. In the
|
||||
latter case, we don't update *LOCUS. We also set the Gigi global variable
|
||||
REF_FILENAME to the reference file name as given by sinput (i.e no
|
||||
directory). */
|
||||
/* Convert SLOC into LOCUS. Return true if SLOC corresponds to a source code
|
||||
location and false if it doesn't. In the former case, set the Gigi global
|
||||
variable REF_FILENAME to the simple debug file name as given by sinput. */
|
||||
|
||||
bool
|
||||
Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
|
||||
{
|
||||
/* If node not from source code, ignore. */
|
||||
if (Sloc < 0)
|
||||
if (Sloc == No_Location)
|
||||
return false;
|
||||
|
||||
if (Sloc <= Standard_Location)
|
||||
#ifdef USE_MAPPED_LOCATION
|
||||
{
|
||||
*locus = BUILTINS_LOCATION;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Source_File_Index file = Get_Source_File_Index (Sloc);
|
||||
Logical_Line_Number line = Get_Logical_Line_Number (Sloc);
|
||||
Column_Number column = Get_Column_Number (Sloc);
|
||||
struct line_map *map = &line_table->maps[file - 1];
|
||||
|
||||
/* Translate the location according to the line-map.h formula. */
|
||||
*locus = map->start_location
|
||||
+ ((line - map->to_line) << map->column_bits)
|
||||
+ (column & ((1 << map->column_bits) - 1));
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
|
||||
/* Use the identifier table to make a hashed, permanent copy of the filename,
|
||||
since the name table gets reallocated after Gigi returns but before all
|
||||
the debugging information is output. The __gnat_to_canonical_file_spec
|
||||
@ -6545,6 +6592,7 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
|
||||
(Get_Name_String (Full_Debug_Name (Get_Source_File_Index (Sloc))))));
|
||||
|
||||
locus->line = Get_Logical_Line_Number (Sloc);
|
||||
#endif
|
||||
|
||||
ref_filename
|
||||
= IDENTIFIER_POINTER
|
||||
@ -6554,18 +6602,18 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Similar to annotate_with_locus, but start with the Sloc of GNAT_NODE and
|
||||
/* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and
|
||||
don't do anything if it doesn't correspond to a source location. */
|
||||
|
||||
static void
|
||||
annotate_with_node (tree node, Node_Id gnat_node)
|
||||
set_expr_location_from_node (tree node, Node_Id gnat_node)
|
||||
{
|
||||
location_t locus;
|
||||
|
||||
if (!Sloc_to_locus (Sloc (gnat_node), &locus))
|
||||
return;
|
||||
|
||||
annotate_with_locus (node, locus);
|
||||
set_expr_location (node, locus);
|
||||
}
|
||||
|
||||
/* Post an error message. MSG is the error message, properly annotated.
|
||||
@ -6714,7 +6762,6 @@ init_code_table (void)
|
||||
gnu_codes[N_Op_Shift_Right_Arithmetic] = RSHIFT_EXPR;
|
||||
}
|
||||
|
||||
#include "gt-ada-trans.h"
|
||||
/* Return a label to branch to for the exception type in KIND or NULL_TREE
|
||||
if none. */
|
||||
|
||||
@ -6730,3 +6777,5 @@ get_exception_label (char kind)
|
||||
else
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
#include "gt-ada-trans.h"
|
||||
|
@ -478,8 +478,6 @@ gnat_pushdecl (tree decl, Node_Id gnat_node)
|
||||
void
|
||||
gnat_init_decl_processing (void)
|
||||
{
|
||||
input_line = 0;
|
||||
|
||||
/* Make the binding_level structure for global names. */
|
||||
current_function_decl = 0;
|
||||
current_binding_level = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user