diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-26 18:47:54 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-26 18:47:54 +0000 |
commit | 9579733ed5bf9976b201cbe8cc2649ea033987bc (patch) | |
tree | 2115d30581d9d9182f2b8de566ba08dcd3742e3b /gcc/fortran | |
parent | 1938132c01eff0ee84005dbd15e6bbf553d5f7ec (diff) | |
download | gcc-9579733ed5bf9976b201cbe8cc2649ea033987bc.tar.gz |
* tree-nested.c (get_nonlocal_vla_type): If not optimizing, call
note_nonlocal_vla_type for nonlocal VLAs.
(note_nonlocal_vla_type, note_nonlocal_block_vlas,
contains_remapped_vars, remap_vla_decls): New functions.
(convert_nonlocal_reference_stmt): If not optimizing, call
note_nonlocal_block_vlas on GIMPLE_BIND block vars.
(nesting_copy_decl): Return {VAR,PARM,RESULT}_DECL unmodified
if it wasn't found in var_map.
(finalize_nesting_tree_1): Call remap_vla_decls. If outermost
GIMPLE_BIND doesn't have gimple_bind_block, chain debug_var_chain
to BLOCK_VARS (DECL_INITIAL (root->context)) instead of calling
declare_vars.
* gimplify.c (nonlocal_vlas): New variable.
(gimplify_var_or_parm_decl): Add debug VAR_DECLs for non-local
referenced VLAs.
(gimplify_body): Create and destroy nonlocal_vlas.
* trans-decl.c: Include pointer-set.h.
(nonlocal_dummy_decl_pset, tree nonlocal_dummy_decls): New variables.
(gfc_nonlocal_dummy_array_decl): New function.
(gfc_get_symbol_decl): Call it for non-local dummy args with saved
descriptor.
(gfc_get_symbol_decl): Set DECL_BY_REFERENCE when needed.
(gfc_generate_function_code): Initialize nonlocal_dummy_decl{s,_pset},
chain it to outermost block's vars, destroy it afterwards.
* Make-lang.in (trans-decl.o): Depend on pointer-set.h.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146810 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 61 |
2 files changed, 62 insertions, 1 deletions
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in index 1600d18b36a..ba81b93b688 100644 --- a/gcc/fortran/Make-lang.in +++ b/gcc/fortran/Make-lang.in @@ -319,7 +319,7 @@ fortran/convert.o: $(GFORTRAN_TRANS_DEPS) fortran/trans.o: $(GFORTRAN_TRANS_DEPS) tree-iterator.h fortran/trans-decl.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-decl.h \ $(CGRAPH_H) $(TARGET_H) $(FUNCTION_H) $(FLAGS_H) $(RTL_H) $(GIMPLE_H) \ - $(TREE_DUMP_H) debug.h + $(TREE_DUMP_H) debug.h pointer-set.h fortran/trans-types.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-types.h \ $(REAL_H) toplev.h $(TARGET_H) $(FLAGS_H) dwarf2out.h fortran/trans-const.o: $(GFORTRAN_TRANS_DEPS) diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 5fe658ecfe7..8f355f6a373 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "debug.h" #include "gfortran.h" +#include "pointer-set.h" #include "trans.h" #include "trans-types.h" #include "trans-array.h" @@ -60,6 +61,8 @@ static GTY(()) tree current_function_return_label; static GTY(()) tree saved_function_decls; static GTY(()) tree saved_parent_function_decls; +static struct pointer_set_t *nonlocal_dummy_decl_pset; +static GTY(()) tree nonlocal_dummy_decls; /* The namespace of the module we're currently generating. Only used while outputting decls for module variables. Do not rely on this being set. */ @@ -870,6 +873,38 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy) return decl; } +/* For symbol SYM with GFC_DECL_SAVED_DESCRIPTOR used in contained + function add a VAR_DECL to the current function with DECL_VALUE_EXPR + pointing to the artificial variable for debug info purposes. */ + +static void +gfc_nonlocal_dummy_array_decl (gfc_symbol *sym) +{ + tree decl, dummy; + + if (! nonlocal_dummy_decl_pset) + nonlocal_dummy_decl_pset = pointer_set_create (); + + if (pointer_set_insert (nonlocal_dummy_decl_pset, sym->backend_decl)) + return; + + dummy = GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl); + decl = build_decl (VAR_DECL, DECL_NAME (dummy), + TREE_TYPE (sym->backend_decl)); + DECL_ARTIFICIAL (decl) = 0; + TREE_USED (decl) = 1; + TREE_PUBLIC (decl) = 0; + TREE_STATIC (decl) = 0; + DECL_EXTERNAL (decl) = 0; + if (DECL_BY_REFERENCE (dummy)) + DECL_BY_REFERENCE (decl) = 1; + DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (sym->backend_decl); + SET_DECL_VALUE_EXPR (decl, sym->backend_decl); + DECL_HAS_VALUE_EXPR_P (decl) = 1; + DECL_CONTEXT (decl) = DECL_CONTEXT (sym->backend_decl); + TREE_CHAIN (decl) = nonlocal_dummy_decls; + nonlocal_dummy_decls = decl; +} /* Return a constant or a variable to use as a string length. Does not add the decl to the current scope. */ @@ -1010,6 +1045,13 @@ gfc_get_symbol_decl (gfc_symbol * sym) { gfc_add_assign_aux_vars (sym); } + + if (sym->attr.dimension + && DECL_LANG_SPECIFIC (sym->backend_decl) + && GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl) + && DECL_CONTEXT (sym->backend_decl) != current_function_decl) + gfc_nonlocal_dummy_array_decl (sym); + return sym->backend_decl; } @@ -1129,6 +1171,13 @@ gfc_get_symbol_decl (gfc_symbol * sym) sym->attr.pointer || sym->attr.allocatable); } + if (!TREE_STATIC (decl) + && POINTER_TYPE_P (TREE_TYPE (decl)) + && !sym->attr.pointer + && !sym->attr.allocatable + && !sym->attr.proc_pointer) + DECL_BY_REFERENCE (decl) = 1; + return decl; } @@ -3852,6 +3901,9 @@ gfc_generate_function_code (gfc_namespace * ns) gfc_generate_contained_functions (ns); + nonlocal_dummy_decls = NULL; + nonlocal_dummy_decl_pset = NULL; + generate_local_vars (ns); /* Keep the parent fake result declaration in module functions @@ -4111,6 +4163,15 @@ gfc_generate_function_code (gfc_namespace * ns) = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl)); + if (nonlocal_dummy_decls) + { + BLOCK_VARS (DECL_INITIAL (fndecl)) + = chainon (BLOCK_VARS (DECL_INITIAL (fndecl)), nonlocal_dummy_decls); + pointer_set_destroy (nonlocal_dummy_decl_pset); + nonlocal_dummy_decls = NULL; + nonlocal_dummy_decl_pset = NULL; + } + /* Output the GENERIC tree. */ dump_function (TDI_original, fndecl); |