From 1d4b96e007641088199133bb37a13338eb4fb2ff Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Thu, 12 Nov 2015 11:55:37 +0100 Subject: [PATCH] decl.c (gnat_to_gnu_entity): Create IMPORTED_DECL nodes to describe the subprogram renamings which are... 2015-11-12 Pierre-Marie de Rodat * gcc-interface/decl.c (gnat_to_gnu_entity): Create IMPORTED_DECL nodes to describe the subprogram renamings which are relevant at debug time. * gcc-interface/gigi.h (get_debug_scope): Add declaration. * gcc-interface/trans.c (Identifier_to_gnu): Consider N_Defining_Operator_Symbol as valid entities. (gnat_to_gnu): Handle N_Defining_Operator_Symbol the same way as other entities. Introduce a specific handling for N_Subprogram_Renaming_Declaration: call gnat_to_gnu_entity on the entity defined for relevant ones. (process_decls): Process subprogram renaming declarations during the second pass only. * gcc-interface/utils.c (get_debug_scope): Make it external. Consider N_Defining_Operator_Symbol as valid entities. (gnat_write_global_declarations): Output debugging information for top-level imported declarations. * gcc-interface/Makefile.in: Fix typo. From-SVN: r230227 --- gcc/ada/ChangeLog | 22 +++++++++++++++++ gcc/ada/gcc-interface/Makefile.in | 2 +- gcc/ada/gcc-interface/decl.c | 29 ++++++++++++++++++++++ gcc/ada/gcc-interface/gigi.h | 5 ++++ gcc/ada/gcc-interface/trans.c | 41 +++++++++++++++++++++++++++++-- gcc/ada/gcc-interface/utils.c | 5 ++-- 6 files changed, 99 insertions(+), 5 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 8e1d8ecdb21..2afdfa2acfd 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,25 @@ +2015-11-12 Pierre-Marie de Rodat + + * gcc-interface/decl.c (gnat_to_gnu_entity): Create + IMPORTED_DECL nodes to describe the subprogram renamings which + are relevant at debug time. + * gcc-interface/gigi.h (get_debug_scope): Add declaration. + * gcc-interface/trans.c (Identifier_to_gnu): Consider + N_Defining_Operator_Symbol as valid entities. + (gnat_to_gnu): Handle N_Defining_Operator_Symbol the same way as + other entities. Introduce a specific handling for + N_Subprogram_Renaming_Declaration: call gnat_to_gnu_entity on + the entity defined for relevant ones. + (process_decls): Process subprogram renaming declarations during + the second pass only. + * gcc-interface/utils.c (get_debug_scope): Make it external. + Consider N_Defining_Operator_Symbol as valid entities. + (gnat_write_global_declarations): Output debugging information + for top-level imported declarations. + * gcc-interface/Makefile.in: Fix typo. + +2015-11-12 Emmanuel Briot + 2015-11-12 Emmanuel Briot * s-os_lib.ads: Documentation update. diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 18ce6d5c244..c2750faeb21 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -148,7 +148,7 @@ GCC_CFLAGS = $(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS) # We don't use cross-make. Instead we use the tools from the build tree, # if they are available. -# program_transform_name and objdir are set by configure.ac. +# program_transform_name and objdir are set by configure.in. program_transform_name = objdir = . diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index b345a886d5e..59754b6bc49 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -4131,6 +4131,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) of its type, so we must elaborate that type now. */ if (Present (Alias (gnat_entity))) { + const Entity_Id gnat_renamed = Renamed_Object (gnat_entity); + if (Ekind (Alias (gnat_entity)) == E_Enumeration_Literal) gnat_to_gnu_entity (Etype (Alias (gnat_entity)), NULL_TREE, 0); @@ -4143,6 +4145,33 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) if (Is_Itype (Etype (gnat_temp))) gnat_to_gnu_entity (Etype (gnat_temp), NULL_TREE, 0); + /* Materialize renamed subprograms in the debugging information + when the renamed object is compile time known. We can consider + such renamings as imported declarations. + + Because the parameters in generics instantiation are generally + materialized as renamings, we ofter end up having both the + renamed subprogram and the renaming in the same context and with + the same name: in this case, renaming is both useless debug-wise + and potentially harmful as name resolution in the debugger could + return twice the same entity! So avoid this case. */ + if (debug_info_p && !artificial_p + && !(get_debug_scope (gnat_entity, NULL) + == get_debug_scope (gnat_renamed, NULL) + && Name_Equals (Chars (gnat_entity), + Chars (gnat_renamed))) + && Present (gnat_renamed) + && (Ekind (gnat_renamed) == E_Function + || Ekind (gnat_renamed) == E_Procedure) + && gnu_decl != NULL_TREE + && TREE_CODE (gnu_decl) == FUNCTION_DECL) + { + tree decl = build_decl (input_location, IMPORTED_DECL, + gnu_entity_name, void_type_node); + IMPORTED_DECL_ASSOCIATED_DECL (decl) = gnu_decl; + gnat_pushdecl (decl, gnat_entity); + } + break; } diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index d7a25662e80..e6fff1e777c 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -1004,6 +1004,11 @@ extern bool renaming_from_generic_instantiation_p (Node_Id gnat_node); don't have a GNU translation. */ extern void process_deferred_decl_context (bool force); +/* Return the innermost scope, starting at GNAT_NODE, we are be interested in + the debug info, or Empty if there is no such scope. If not NULL, set + IS_SUBPROGRAM to whether the returned entity is a subprogram. */ +extern Entity_Id get_debug_scope (Node_Id gnat_node, bool *is_subprogram); + #ifdef __cplusplus extern "C" { #endif diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index a347b3b1a42..b23cc511092 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -1027,7 +1027,8 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) original type. Similarly, a class-wide type is equivalent to a subtype of itself. Finally, if the types are Itypes, one may be a copy of the other, which is also legal. */ - gnat_temp = (Nkind (gnat_node) == N_Defining_Identifier + gnat_temp = ((Nkind (gnat_node) == N_Defining_Identifier + || Nkind (gnat_node) == N_Defining_Operator_Symbol) ? gnat_node : Entity (gnat_node)); gnat_temp_type = Etype (gnat_temp); @@ -5694,6 +5695,7 @@ gnat_to_gnu (Node_Id gnat_node) case N_Expanded_Name: case N_Operator_Symbol: case N_Defining_Identifier: + case N_Defining_Operator_Symbol: gnu_result = Identifier_to_gnu (gnat_node, &gnu_result_type); /* If atomic access is required on the RHS, build the atomic load. */ @@ -5957,13 +5959,39 @@ gnat_to_gnu (Node_Id gnat_node) } break; + case N_Subprogram_Renaming_Declaration: + { + const Node_Id gnat_renaming = Defining_Entity (gnat_node); + const Node_Id gnat_renamed = Renamed_Entity (gnat_renaming); + + gnu_result = alloc_stmt_list (); + + /* Materializing renamed subprograms will only benefit the debugging + information as they aren't referenced in the generated code. So + skip them when they aren't needed. Avoid doing this if: + + - there is a freeze node: in this case the renamed entity is not + elaborated yet; + - the renamed subprogram is intrinsic: it will not be available in + the debugging information (note that both or only one of the + renaming and the renamed subprograms can be intrinsic). */ + if (No (Freeze_Node (gnat_renaming)) + && Needs_Debug_Info (gnat_renaming) + && Present (gnat_renamed) + && (Ekind (gnat_renamed) == E_Function + || Ekind (gnat_renamed) == E_Procedure) + && !Is_Intrinsic_Subprogram (gnat_renaming) + && !Is_Intrinsic_Subprogram (gnat_renamed)) + gnat_to_gnu_entity (gnat_renaming, gnat_to_gnu (gnat_renamed), 1); + break; + } + case N_Implicit_Label_Declaration: gnat_to_gnu_entity (Defining_Entity (gnat_node), NULL_TREE, 1); gnu_result = alloc_stmt_list (); break; case N_Number_Declaration: - case N_Subprogram_Renaming_Declaration: case N_Package_Renaming_Declaration: /* These are fully handled in the front end. */ /* ??? For package renamings, find a way to use GENERIC namespaces so @@ -8553,6 +8581,12 @@ process_decls (List_Id gnat_decls, List_Id gnat_decls2, || Nkind (gnat_decl) == N_Protected_Body_Stub) ; + /* Renamed subprograms may not be elaborated yet at this point + since renamings do not trigger freezing. Wait for the second + pass to take care of them. */ + else if (Nkind (gnat_decl) == N_Subprogram_Renaming_Declaration) + ; + else add_stmt (gnat_to_gnu (gnat_decl)); } @@ -8581,6 +8615,9 @@ process_decls (List_Id gnat_decls, List_Id gnat_decls2, else if (Nkind (gnat_decl) == N_Freeze_Entity) process_decls (Actions (gnat_decl), Empty, Empty, false, true); + + else if (Nkind (gnat_decl) == N_Subprogram_Renaming_Declaration) + add_stmt (gnat_to_gnu (gnat_decl)); } } diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 1e9e93614c6..b032ae03df7 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -585,7 +585,7 @@ gnat_set_type_context (tree type, tree context) the debug info, or Empty if there is no such scope. If not NULL, set IS_SUBPROGRAM to whether the returned entity is a subprogram. */ -static Entity_Id +Entity_Id get_debug_scope (Node_Id gnat_node, bool *is_subprogram) { Entity_Id gnat_entity; @@ -593,7 +593,8 @@ get_debug_scope (Node_Id gnat_node, bool *is_subprogram) if (is_subprogram) *is_subprogram = false; - if (Nkind (gnat_node) == N_Defining_Identifier) + if (Nkind (gnat_node) == N_Defining_Identifier + || Nkind (gnat_node) == N_Defining_Operator_Symbol) gnat_entity = Scope (gnat_node); else return Empty; -- 2.30.2