1 /* Scan linker error messages for missing template instantiations and provide
4 Copyright (C) 1995, 1998, 1999 Free Software Foundation, Inc.
5 Contributed by Jason Merrill (jason@cygnus.com).
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
30 #define MAX_ITERATIONS 17
32 /* Obstack allocation and deallocation routines. */
33 #define obstack_chunk_alloc xmalloc
34 #define obstack_chunk_free free
36 /* Defined in the automatically-generated underscore.c. */
37 extern int prepends_underscore
;
39 static int tlink_verbose
;
41 /* Hash table boilerplate for working with hash.[ch]. We have hash tables
42 for symbol names, file names, and demangled symbols. */
44 typedef struct symbol_hash_entry
46 struct hash_entry root
;
47 struct file_hash_entry
*file
;
53 typedef struct file_hash_entry
55 struct hash_entry root
;
62 typedef struct demangled_hash_entry
64 struct hash_entry root
;
68 static struct hash_table symbol_table
;
70 static struct hash_entry
* symbol_hash_newfunc
PARAMS ((struct hash_entry
*,
73 static struct symbol_hash_entry
* symbol_hash_lookup
PARAMS ((const char *,
75 static struct hash_entry
* file_hash_newfunc
PARAMS ((struct hash_entry
*,
78 static struct file_hash_entry
* file_hash_lookup
PARAMS ((const char *));
79 static struct hash_entry
* demangled_hash_newfunc
PARAMS ((struct hash_entry
*,
82 static struct demangled_hash_entry
*
83 demangled_hash_lookup
PARAMS ((const char *, boolean
));
84 static void symbol_push
PARAMS ((symbol
*));
85 static symbol
* symbol_pop
PARAMS ((void));
86 static void file_push
PARAMS ((file
*));
87 static file
* file_pop
PARAMS ((void));
88 static void tlink_init
PARAMS ((void));
89 static int tlink_execute
PARAMS ((const char *, char **, const char *));
90 static char * frob_extension
PARAMS ((const char *, const char *));
91 static char * obstack_fgets
PARAMS ((FILE *, struct obstack
*));
92 static char * tfgets
PARAMS ((FILE *));
93 static char * pfgets
PARAMS ((FILE *));
94 static void freadsym
PARAMS ((FILE *, file
*, int));
95 static void read_repo_file
PARAMS ((file
*));
96 static void maybe_tweak
PARAMS ((char *, file
*));
97 static int recompile_files
PARAMS ((void));
98 static int read_repo_files
PARAMS ((char **));
99 static void demangle_new_symbols
PARAMS ((void));
100 static int scan_linker_output
PARAMS ((const char *));
102 /* Create a new entry for the symbol hash table.
103 Passed to hash_table_init. */
105 static struct hash_entry
*
106 symbol_hash_newfunc (entry
, table
, string
)
107 struct hash_entry
*entry
;
108 struct hash_table
*table
;
109 hash_table_key string ATTRIBUTE_UNUSED
;
111 struct symbol_hash_entry
*ret
= (struct symbol_hash_entry
*) entry
;
114 ret
= ((struct symbol_hash_entry
*)
115 hash_allocate (table
, sizeof (struct symbol_hash_entry
)));
123 return (struct hash_entry
*) ret
;
126 /* Look up an entry in the symbol hash table. */
128 static struct symbol_hash_entry
*
129 symbol_hash_lookup (string
, create
)
133 return ((struct symbol_hash_entry
*)
134 hash_lookup (&symbol_table
, (const hash_table_key
) string
,
135 create
, string_copy
));
138 static struct hash_table file_table
;
140 /* Create a new entry for the file hash table.
141 Passed to hash_table_init. */
143 static struct hash_entry
*
144 file_hash_newfunc (entry
, table
, string
)
145 struct hash_entry
*entry
;
146 struct hash_table
*table
;
147 hash_table_key string ATTRIBUTE_UNUSED
;
149 struct file_hash_entry
*ret
= (struct file_hash_entry
*) entry
;
152 ret
= ((struct file_hash_entry
*)
153 hash_allocate (table
, sizeof (struct file_hash_entry
)));
161 return (struct hash_entry
*) ret
;
164 /* Look up an entry in the file hash table. */
166 static struct file_hash_entry
*
167 file_hash_lookup (string
)
170 return ((struct file_hash_entry
*)
171 hash_lookup (&file_table
, (const hash_table_key
) string
, true,
175 static struct hash_table demangled_table
;
177 /* Create a new entry for the demangled name hash table.
178 Passed to hash_table_init. */
180 static struct hash_entry
*
181 demangled_hash_newfunc (entry
, table
, string
)
182 struct hash_entry
*entry
;
183 struct hash_table
*table
;
184 hash_table_key string ATTRIBUTE_UNUSED
;
186 struct demangled_hash_entry
*ret
= (struct demangled_hash_entry
*) entry
;
189 ret
= ((struct demangled_hash_entry
*)
190 hash_allocate (table
, sizeof (struct demangled_hash_entry
)));
195 return (struct hash_entry
*) ret
;
198 /* Look up an entry in the demangled name hash table. */
200 static struct demangled_hash_entry
*
201 demangled_hash_lookup (string
, create
)
205 return ((struct demangled_hash_entry
*)
206 hash_lookup (&demangled_table
, (const hash_table_key
) string
,
207 create
, string_copy
));
212 struct symbol_stack_entry
215 struct symbol_stack_entry
*next
;
217 struct obstack symbol_stack_obstack
;
218 struct symbol_stack_entry
*symbol_stack
;
220 struct file_stack_entry
223 struct file_stack_entry
*next
;
225 struct obstack file_stack_obstack
;
226 struct file_stack_entry
*file_stack
;
232 struct symbol_stack_entry
*ep
= (struct symbol_stack_entry
*) obstack_alloc
233 (&symbol_stack_obstack
, sizeof (struct symbol_stack_entry
));
235 ep
->next
= symbol_stack
;
242 struct symbol_stack_entry
*ep
= symbol_stack
;
247 symbol_stack
= ep
->next
;
248 obstack_free (&symbol_stack_obstack
, ep
);
256 struct file_stack_entry
*ep
;
261 ep
= (struct file_stack_entry
*) obstack_alloc
262 (&file_stack_obstack
, sizeof (struct file_stack_entry
));
264 ep
->next
= file_stack
;
272 struct file_stack_entry
*ep
= file_stack
;
277 file_stack
= ep
->next
;
278 obstack_free (&file_stack_obstack
, ep
);
283 /* Other machinery. */
285 /* Initialize the tlink machinery. Called from do_tlink. */
292 hash_table_init (&symbol_table
, symbol_hash_newfunc
, string_hash
,
294 hash_table_init (&file_table
, file_hash_newfunc
, string_hash
,
296 hash_table_init (&demangled_table
, demangled_hash_newfunc
,
297 string_hash
, string_compare
);
298 obstack_begin (&symbol_stack_obstack
, 0);
299 obstack_begin (&file_stack_obstack
, 0);
301 p
= getenv ("TLINK_VERBOSE");
303 tlink_verbose
= atoi (p
);
315 tlink_execute (prog
, argv
, redir
)
320 collect_execute (prog
, argv
, redir
);
321 return collect_wait (prog
);
325 frob_extension (s
, ext
)
329 const char *p
= rindex (s
, '/');
336 obstack_grow (&temporary_obstack
, s
, p
- s
);
337 return obstack_copy0 (&temporary_obstack
, ext
, strlen (ext
));
341 obstack_fgets (stream
, ob
)
346 while ((c
= getc (stream
)) != EOF
&& c
!= '\n')
347 obstack_1grow (ob
, c
);
348 if (obstack_object_size (ob
) == 0)
350 obstack_1grow (ob
, '\0');
351 return obstack_finish (ob
);
358 return obstack_fgets (stream
, &temporary_obstack
);
365 return obstack_fgets (stream
, &permanent_obstack
);
368 /* Real tlink code. */
370 /* Subroutine of read_repo_file. We are reading the repo file for file F,
371 which is coming in on STREAM, and the symbol that comes next in STREAM
372 is offerred, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
374 XXX "provided" is unimplemented, both here and in the compiler. */
377 freadsym (stream
, f
, chosen
)
385 const char *name
= tfgets (stream
);
386 sym
= symbol_hash_lookup (name
, true);
389 if (sym
->file
== NULL
)
391 /* We didn't have this symbol already, so we choose this file. */
395 sym
->chosen
= chosen
;
399 /* We want this file; cast aside any pretender. */
401 if (sym
->chosen
&& sym
->file
!= f
)
403 if (sym
->chosen
== 1)
404 file_push (sym
->file
);
409 chosen
= sym
->chosen
;
413 sym
->chosen
= chosen
;
417 /* Read in the repo file denoted by F, and record all its information. */
424 FILE *stream
= fopen ((char*) f
->root
.key
, "r");
426 if (tlink_verbose
>= 2)
427 fprintf (stderr
, "collect: reading %s\n",
428 (char*) f
->root
.key
);
430 while (fscanf (stream
, "%c ", &c
) == 1)
435 f
->args
= pfgets (stream
);
438 f
->dir
= pfgets (stream
);
441 f
->main
= pfgets (stream
);
444 freadsym (stream
, f
, 2);
447 freadsym (stream
, f
, 1);
450 freadsym (stream
, f
, 0);
453 obstack_free (&temporary_obstack
, temporary_firstobj
);
457 f
->args
= getenv ("COLLECT_GCC_OPTIONS");
462 /* We might want to modify LINE, which is a symbol line from file F. We do
463 this if either we saw an error message referring to the symbol in
464 question, or we have already allocated the symbol to another file and
465 this one wants to emit it as well. */
468 maybe_tweak (line
, f
)
472 symbol
*sym
= symbol_hash_lookup (line
+ 2, false);
474 if ((sym
->file
== f
&& sym
->tweaking
)
475 || (sym
->file
!= f
&& line
[0] == 'C'))
487 /* Update the repo files for each of the object files we have adjusted and
490 XXX Should this use collect_execute instead of system? */
497 while ((f
= file_pop ()) != NULL
)
499 char *line
, *command
;
500 FILE *stream
= fopen ((char*) f
->root
.key
, "r");
501 const char *outname
= frob_extension ((char*) f
->root
.key
, ".rnw");
502 FILE *output
= fopen (outname
, "w");
504 while ((line
= tfgets (stream
)) != NULL
)
510 maybe_tweak (line
, f
);
512 fprintf (output
, "%s\n", line
);
516 rename (outname
, (char*) f
->root
.key
);
518 obstack_grow (&temporary_obstack
, "cd ", 3);
519 obstack_grow (&temporary_obstack
, f
->dir
, strlen (f
->dir
));
520 obstack_grow (&temporary_obstack
, "; ", 2);
521 obstack_grow (&temporary_obstack
, c_file_name
, strlen (c_file_name
));
522 obstack_1grow (&temporary_obstack
, ' ');
523 obstack_grow (&temporary_obstack
, f
->args
, strlen (f
->args
));
524 obstack_1grow (&temporary_obstack
, ' ');
525 command
= obstack_copy0 (&temporary_obstack
, f
->main
, strlen (f
->main
));
528 fprintf (stderr
, "collect: recompiling %s\n", f
->main
);
529 if (tlink_verbose
>= 3)
530 fprintf (stderr
, "%s\n", command
);
532 if (system (command
) != 0)
537 obstack_free (&temporary_obstack
, temporary_firstobj
);
542 /* The first phase of processing: determine which object files have
543 .rpo files associated with them, and read in the information. */
546 read_repo_files (object_lst
)
549 char **object
= object_lst
;
551 for (; *object
; object
++)
553 const char *p
= frob_extension (*object
, ".rpo");
556 if (! file_exists (p
))
559 f
= file_hash_lookup (p
);
564 if (file_stack
!= NULL
&& ! recompile_files ())
567 return (symbol_stack
!= NULL
);
570 /* Add the demangled forms of any new symbols to the hash table. */
573 demangle_new_symbols ()
577 while ((sym
= symbol_pop ()) != NULL
)
580 const char *p
= cplus_demangle ((char*) sym
->root
.key
,
581 DMGL_PARAMS
| DMGL_ANSI
);
586 dem
= demangled_hash_lookup (p
, true);
587 dem
->mangled
= (char*) sym
->root
.key
;
591 /* Step through the output of the linker, in the file named FNAME, and
592 adjust the settings for each symbol encountered. */
595 scan_linker_output (fname
)
598 FILE *stream
= fopen (fname
, "r");
601 while ((line
= tfgets (stream
)) != NULL
)
607 while (*p
&& ISSPACE ((unsigned char)*p
))
613 for (q
= p
; *q
&& ! ISSPACE ((unsigned char)*q
); ++q
)
616 /* Try the first word on the line. */
619 if (*p
== '_' && prepends_underscore
)
624 sym
= symbol_hash_lookup (p
, false);
627 /* Try a mangled name in quotes. */
629 const char *oldq
= q
+1;
633 /* First try `GNU style'. */
634 p
= index (oldq
, '`');
636 p
++, q
= index (p
, '\'');
637 /* Then try "double quotes". */
638 else if (p
= index (oldq
, '"'), p
)
639 p
++, q
= index (p
, '"');
641 /* We need to check for certain error keywords here, or we would
642 mistakenly use GNU ld's "In function `foo':" message. */
643 if (q
&& (strstr (oldq
, "ndefined")
644 || strstr (oldq
, "nresolved")
645 || strstr (oldq
, "ultiple")))
648 dem
= demangled_hash_lookup (p
, false);
650 sym
= symbol_hash_lookup (dem
->mangled
, false);
653 if (*p
== '_' && prepends_underscore
)
655 sym
= symbol_hash_lookup (p
, false);
660 if (sym
&& sym
->tweaked
)
665 if (sym
&& !sym
->tweaking
)
667 if (tlink_verbose
>= 2)
668 fprintf (stderr
, "collect: tweaking %s in %s\n",
669 (char*) sym
->root
.key
, (char*) sym
->file
->root
.key
);
671 file_push (sym
->file
);
674 obstack_free (&temporary_obstack
, temporary_firstobj
);
678 return (file_stack
!= NULL
);
681 /* Entry point for tlink. Called from main in collect2.c.
683 Iteratively try to provide definitions for all the unresolved symbols
684 mentioned in the linker error messages.
686 LD_ARGV is an array of arguments for the linker.
687 OBJECT_LST is an array of object files that we may be able to recompile
688 to provide missing definitions. Currently ignored. */
691 do_tlink (ld_argv
, object_lst
)
692 char **ld_argv
, **object_lst ATTRIBUTE_UNUSED
;
694 int exit
= tlink_execute ("ld", ld_argv
, ldout
);
702 /* Until collect does a better job of figuring out which are object
703 files, assume that everything on the command line could be. */
704 if (read_repo_files (ld_argv
))
705 while (exit
&& i
++ < MAX_ITERATIONS
)
707 if (tlink_verbose
>= 3)
709 demangle_new_symbols ();
710 if (! scan_linker_output (ldout
))
712 if (! recompile_files ())
715 fprintf (stderr
, "collect: relinking\n");
716 exit
= tlink_execute ("ld", ld_argv
, ldout
);
724 error ("ld returned %d exit status", exit
);