summaryrefslogtreecommitdiff
path: root/gcc/fortran/match.c
diff options
context:
space:
mode:
authorjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-29 17:19:32 +0000
committerjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-29 17:19:32 +0000
commit7b2060ba65acd2fdcbf0dedd5ad0a268b2028b51 (patch)
tree9cf48d558f50c1053b18c202c9c36d7a8a46c9f8 /gcc/fortran/match.c
parent3e6bf5fe04413ffdcf981bf74684309cb7cf6800 (diff)
downloadgcc-7b2060ba65acd2fdcbf0dedd5ad0a268b2028b51.tar.gz
PR 51808 Support arbitrarily long bind(C) binding labels.
2012-01-29 Janne Blomqvist <jb@gcc.gnu.org> PR fortran/51808 * decl.c (set_binding_label): Move prototype from match.h to here. (curr_binding_label): Make a pointer rather than static array. (build_sym): Check sym->binding_label pointer rather than array, update set_binding_label call, handle curr_binding_label changes. (set_binding_label): Handle new curr_binding_label, dest_label double ptr, and sym->binding_label. (verify_bind_c_sym): Handle sym->binding_label being a pointer. (set_verify_bind_c_sym): Check sym->binding_label pointer rather than array, update set_binding_label call. (gfc_match_bind_c_stmt): Handle curr_binding_label change. (match_procedure_decl): Update set_binding_label call. (gfc_match_bind_c): Change binding_label to pointer, update gfc_match_name_C call. * gfortran.h (GFC_MAX_BINDING_LABEL_LEN): Remove macro. (gfc_symbol): Make binding_label a pointer. (gfc_common_head): Likewise. * match.c (gfc_match_name_C): Heap allocate bind(C) name. * match.h (gfc_match_name_C): Change prototype argument. (set_binding_label): Move prototype to decl.c. * module.c (struct pointer_info): Make binding_label a pointer. (free_pi_tree): Free unused binding_label. (mio_read_string): New function. (mio_write_string): New function. (load_commons): Redo reading of binding_label. (read_module): Likewise. (write_common_0): Change to write empty string instead of name if no binding_label. (write_blank_common): Write empty string for binding label. (write_symbol): Change to write empty string instead of name if no binding_label. * resolve.c (gfc_iso_c_func_interface): Don't set binding_label. (set_name_and_label): Make binding_label double pointer, use asprintf. (gfc_iso_c_sub_interface): Make binding_label a pointer. (resolve_bind_c_comms): Handle cases if gfc_common_head->binding_label is NULL. (gfc_verify_binding_labels): sym->binding_label is a pointer. * symbol.c (gfc_free_symbol): Free binding_label. (gfc_new_symbol): Rely on XCNEW zero init for binding_label. (gen_special_c_interop_ptr): Don't set binding label. (generate_isocbinding_symbol): Insert binding_label into symbol table. (get_iso_c_sym): Use pointer assignment instead of strcpy. * trans-common.c (gfc_sym_mangled_common_id): Handle com->binding_label being a pointer. * trans-decl.c (gfc_sym_mangled_identifier): Handle sym->binding_label being a pointer. (gfc_sym_mangled_function_id): Likewise. testsuite ChangeLog 2012-01-29 Janne Blomqvist <jb@gcc.gnu.org> PR fortran/51808 * gfortran.dg/module_md5_1.f90: Update MD5 sum. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183677 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/match.c')
-rw-r--r--gcc/fortran/match.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 05853081173..3024cc7b9c9 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1,6 +1,6 @@
/* Matching subroutines in all sizes, shapes and colors.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010, 2011
+ 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Andy Vaught
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "gfortran.h"
#include "match.h"
#include "parse.h"
+#include "tree.h"
int gfc_matching_ptr_assignment = 0;
int gfc_matching_procptr_assignment = 0;
@@ -571,22 +572,22 @@ gfc_match_name (char *buffer)
/* Match a valid name for C, which is almost the same as for Fortran,
except that you can start with an underscore, etc.. It could have
been done by modifying the gfc_match_name, but this way other
- things C allows can be added, such as no limits on the length.
- Right now, the length is limited to the same thing as Fortran..
+ things C allows can be done, such as no limits on the length.
Also, by rewriting it, we use the gfc_next_char_C() to prevent the
input characters from being automatically lower cased, since C is
case sensitive. The parameter, buffer, is used to return the name
- that is matched. Return MATCH_ERROR if the name is too long
- (though this is a self-imposed limit), MATCH_NO if what we're
- seeing isn't a name, and MATCH_YES if we successfully match a C
- name. */
+ that is matched. Return MATCH_ERROR if the name is not a valid C
+ name, MATCH_NO if what we're seeing isn't a name, and MATCH_YES if
+ we successfully match a C name. */
match
-gfc_match_name_C (char *buffer)
+gfc_match_name_C (char **buffer)
{
locus old_loc;
- int i = 0;
+ size_t i = 0;
gfc_char_t c;
+ char* buf;
+ size_t cursz = 16;
old_loc = gfc_current_locus;
gfc_gobble_whitespace ();
@@ -600,7 +601,6 @@ gfc_match_name_C (char *buffer)
symbol name, all lowercase. */
if (c == '"' || c == '\'')
{
- buffer[0] = '\0';
gfc_current_locus = old_loc;
return MATCH_YES;
}
@@ -611,24 +611,19 @@ gfc_match_name_C (char *buffer)
return MATCH_ERROR;
}
+ buf = XNEWVEC (char, cursz);
/* Continue to read valid variable name characters. */
do
{
gcc_assert (gfc_wide_fits_in_byte (c));
- buffer[i++] = (unsigned char) c;
-
- /* C does not define a maximum length of variable names, to my
- knowledge, but the compiler typically places a limit on them.
- For now, i'll use the same as the fortran limit for simplicity,
- but this may need to be changed to a dynamic buffer that can
- be realloc'ed here if necessary, or more likely, a larger
- upper-bound set. */
- if (i > gfc_option.max_identifier_length)
- {
- gfc_error ("Name at %C is too long");
- return MATCH_ERROR;
- }
+ buf[i++] = (unsigned char) c;
+
+ if (i >= cursz)
+ {
+ cursz *= 2;
+ buf = XRESIZEVEC (char, buf, cursz);
+ }
old_loc = gfc_current_locus;
@@ -636,7 +631,11 @@ gfc_match_name_C (char *buffer)
c = gfc_next_char_literal (INSTRING_WARN);
} while (ISALNUM (c) || c == '_');
- buffer[i] = '\0';
+ /* The binding label will be needed later anyway, so just insert it
+ into the symbol table. */
+ buf[i] = '\0';
+ *buffer = IDENTIFIER_POINTER (get_identifier (buf));
+ XDELETEVEC (buf);
gfc_current_locus = old_loc;
/* See if we stopped because of whitespace. */