1 /* Scan linker error messages for missing template instantiations and provide
4 Copyright (C) 1995, 1998 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #define MAX_ITERATIONS 17
31 /* Obstack allocation and deallocation routines. */
32 #define obstack_chunk_alloc xmalloc
33 #define obstack_chunk_free free
35 /* Defined in collect2.c. */
36 extern int vflag
, debug
;
38 extern char *c_file_name
;
39 extern struct obstack temporary_obstack
;
40 extern struct obstack permanent_obstack
;
41 extern char * temporary_firstobj
;
43 /* Defined in the automatically-generated underscore.c. */
44 extern int prepends_underscore
;
46 static int tlink_verbose
;
48 /* Hash table code. */
50 typedef struct symbol_hash_entry
52 struct hash_entry root
;
53 struct file_hash_entry
*file
;
59 typedef struct file_hash_entry
61 struct hash_entry root
;
68 typedef struct demangled_hash_entry
70 struct hash_entry root
;
74 static struct hash_table symbol_table
;
76 static struct hash_entry
*
77 symbol_hash_newfunc (entry
, table
, string
)
78 struct hash_entry
*entry
;
79 struct hash_table
*table
;
82 struct symbol_hash_entry
*ret
= (struct symbol_hash_entry
*) entry
;
85 ret
= ((struct symbol_hash_entry
*)
86 hash_allocate (table
, sizeof (struct symbol_hash_entry
)));
90 ret
= ((struct symbol_hash_entry
*)
91 hash_newfunc ((struct hash_entry
*) ret
, table
,
92 (hash_table_key
) string
));
97 return (struct hash_entry
*) ret
;
100 static struct symbol_hash_entry
*
101 symbol_hash_lookup (string
, create
)
105 return ((struct symbol_hash_entry
*)
106 hash_lookup (&symbol_table
, (hash_table_key
) string
,
107 create
, &string_copy
));
110 static struct hash_table file_table
;
112 static struct hash_entry
*
113 file_hash_newfunc (entry
, table
, string
)
114 struct hash_entry
*entry
;
115 struct hash_table
*table
;
118 struct file_hash_entry
*ret
= (struct file_hash_entry
*) entry
;
121 ret
= ((struct file_hash_entry
*)
122 hash_allocate (table
, sizeof (struct file_hash_entry
)));
126 ret
= ((struct file_hash_entry
*)
127 hash_newfunc ((struct hash_entry
*) ret
, table
,
128 (hash_table_key
) string
));
133 return (struct hash_entry
*) ret
;
136 static struct file_hash_entry
*
137 file_hash_lookup (string
)
140 return ((struct file_hash_entry
*)
141 hash_lookup (&file_table
, (hash_table_key
) string
, true,
145 static struct hash_table demangled_table
;
147 static struct hash_entry
*
148 demangled_hash_newfunc (entry
, table
, string
)
149 struct hash_entry
*entry
;
150 struct hash_table
*table
;
153 struct demangled_hash_entry
*ret
= (struct demangled_hash_entry
*) entry
;
156 ret
= ((struct demangled_hash_entry
*)
157 hash_allocate (table
, sizeof (struct demangled_hash_entry
)));
161 ret
= ((struct demangled_hash_entry
*)
162 hash_newfunc ((struct hash_entry
*) ret
, table
,
163 (hash_table_key
) string
));
165 return (struct hash_entry
*) ret
;
168 static struct demangled_hash_entry
*
169 demangled_hash_lookup (string
, create
)
173 return ((struct demangled_hash_entry
*)
174 hash_lookup (&demangled_table
, (hash_table_key
) string
,
175 create
, &string_copy
));
180 struct symbol_stack_entry
183 struct symbol_stack_entry
*next
;
185 struct obstack symbol_stack_obstack
;
186 struct symbol_stack_entry
*symbol_stack
;
188 struct file_stack_entry
191 struct file_stack_entry
*next
;
193 struct obstack file_stack_obstack
;
194 struct file_stack_entry
*file_stack
;
200 struct symbol_stack_entry
*ep
= (struct symbol_stack_entry
*) obstack_alloc
201 (&symbol_stack_obstack
, sizeof (struct symbol_stack_entry
));
203 ep
->next
= symbol_stack
;
210 struct symbol_stack_entry
*ep
= symbol_stack
;
215 symbol_stack
= ep
->next
;
216 obstack_free (&symbol_stack_obstack
, ep
);
224 struct file_stack_entry
*ep
;
229 ep
= (struct file_stack_entry
*) obstack_alloc
230 (&file_stack_obstack
, sizeof (struct file_stack_entry
));
232 ep
->next
= file_stack
;
240 struct file_stack_entry
*ep
= file_stack
;
245 file_stack
= ep
->next
;
246 obstack_free (&file_stack_obstack
, ep
);
251 /* Other machinery. */
258 hash_table_init (&symbol_table
, symbol_hash_newfunc
, &string_hash
,
260 hash_table_init (&file_table
, file_hash_newfunc
, &string_hash
,
262 hash_table_init (&demangled_table
, demangled_hash_newfunc
,
263 &string_hash
, &string_compare
);
264 obstack_begin (&symbol_stack_obstack
, 0);
265 obstack_begin (&file_stack_obstack
, 0);
267 p
= getenv ("TLINK_VERBOSE");
269 tlink_verbose
= atoi (p
);
281 tlink_execute (prog
, argv
, redir
)
286 collect_execute (prog
, argv
, redir
);
287 return collect_wait (prog
);
291 frob_extension (s
, ext
)
294 char *p
= rindex (s
, '/');
301 obstack_grow (&temporary_obstack
, s
, p
- s
);
302 return obstack_copy0 (&temporary_obstack
, ext
, strlen (ext
));
306 obstack_fgets (stream
, ob
)
311 while ((c
= getc (stream
)) != EOF
&& c
!= '\n')
312 obstack_1grow (ob
, c
);
313 if (obstack_object_size (ob
) == 0)
315 obstack_1grow (ob
, '\0');
316 return obstack_finish (ob
);
323 return obstack_fgets (stream
, &temporary_obstack
);
330 return obstack_fgets (stream
, &permanent_obstack
);
333 /* Real tlink code. */
336 freadsym (stream
, f
, chosen
)
344 char *name
= tfgets (stream
);
345 sym
= symbol_hash_lookup (name
, true);
348 if (sym
->file
== NULL
)
352 sym
->chosen
= chosen
;
356 if (sym
->chosen
&& sym
->file
!= f
)
358 if (sym
->chosen
== 1)
359 file_push (sym
->file
);
364 chosen
= sym
->chosen
;
368 sym
->chosen
= chosen
;
377 FILE *stream
= fopen ((char*) f
->root
.key
, "r");
379 if (tlink_verbose
>= 2)
380 fprintf (stderr
, "collect: reading %s\n",
381 (char*) f
->root
.key
);
383 while (fscanf (stream
, "%c ", &c
) == 1)
388 f
->args
= pfgets (stream
);
391 f
->dir
= pfgets (stream
);
394 f
->main
= pfgets (stream
);
397 freadsym (stream
, f
, 2);
400 freadsym (stream
, f
, 1);
403 freadsym (stream
, f
, 0);
406 obstack_free (&temporary_obstack
, temporary_firstobj
);
410 f
->args
= getenv ("COLLECT_GCC_OPTIONS");
416 maybe_tweak (line
, f
)
420 symbol
*sym
= symbol_hash_lookup (line
+ 2, false);
422 if ((sym
->file
== f
&& sym
->tweaking
)
423 || (sym
->file
!= f
&& line
[0] == 'C'))
440 while ((f
= file_pop ()) != NULL
)
442 char *line
, *command
;
443 FILE *stream
= fopen ((char*) f
->root
.key
, "r");
444 char *outname
= frob_extension ((char*) f
->root
.key
, ".rnw");
445 FILE *output
= fopen (outname
, "w");
447 while ((line
= tfgets (stream
)) != NULL
)
453 maybe_tweak (line
, f
);
455 fprintf (output
, "%s\n", line
);
459 rename (outname
, (char*) f
->root
.key
);
461 obstack_grow (&temporary_obstack
, "cd ", 3);
462 obstack_grow (&temporary_obstack
, f
->dir
, strlen (f
->dir
));
463 obstack_grow (&temporary_obstack
, "; ", 2);
464 obstack_grow (&temporary_obstack
, c_file_name
, strlen (c_file_name
));
465 obstack_1grow (&temporary_obstack
, ' ');
466 obstack_grow (&temporary_obstack
, f
->args
, strlen (f
->args
));
467 obstack_1grow (&temporary_obstack
, ' ');
468 command
= obstack_copy0 (&temporary_obstack
, f
->main
, strlen (f
->main
));
471 fprintf (stderr
, "collect: recompiling %s\n", f
->main
);
472 if (tlink_verbose
>= 3)
473 fprintf (stderr
, "%s\n", command
);
475 if (system (command
) != 0)
480 obstack_free (&temporary_obstack
, temporary_firstobj
);
486 read_repo_files (object_lst
)
489 char **object
= object_lst
;
491 for (; *object
; object
++)
493 char *p
= frob_extension (*object
, ".rpo");
496 if (! file_exists (p
))
499 f
= file_hash_lookup (p
);
504 if (file_stack
!= NULL
&& ! recompile_files ())
507 return (symbol_stack
!= NULL
);
511 demangle_new_symbols ()
515 while ((sym
= symbol_pop ()) != NULL
)
518 char *p
= cplus_demangle ((char*) sym
->root
.key
,
519 DMGL_PARAMS
| DMGL_ANSI
);
524 dem
= demangled_hash_lookup (p
, true);
525 dem
->mangled
= (char*) sym
->root
.key
;
530 scan_linker_output (fname
)
533 FILE *stream
= fopen (fname
, "r");
536 while ((line
= tfgets (stream
)) != NULL
)
542 while (*p
&& ISSPACE ((unsigned char)*p
))
548 for (q
= p
; *q
&& ! ISSPACE ((unsigned char)*q
); ++q
)
551 /* Try the first word on the line. */
554 if (*p
== '_' && prepends_underscore
)
559 sym
= symbol_hash_lookup (p
, false);
562 /* Try a mangled name in quotes. */
568 /* First try `GNU style'. */
569 p
= index (oldq
, '`');
571 p
++, q
= index (p
, '\'');
572 /* Then try "double quotes". */
573 else if (p
= index (oldq
, '"'), p
)
574 p
++, q
= index (p
, '"');
579 dem
= demangled_hash_lookup (p
, false);
581 sym
= symbol_hash_lookup (dem
->mangled
, false);
583 sym
= symbol_hash_lookup (p
, false);
587 if (sym
&& sym
->tweaked
)
592 if (sym
&& !sym
->tweaking
)
594 if (tlink_verbose
>= 2)
595 fprintf (stderr
, "collect: tweaking %s in %s\n",
596 (char*) sym
->root
.key
, (char*) sym
->file
->root
.key
);
598 file_push (sym
->file
);
601 obstack_free (&temporary_obstack
, temporary_firstobj
);
605 return (file_stack
!= NULL
);
609 do_tlink (ld_argv
, object_lst
)
610 char **ld_argv
, **object_lst
;
612 int exit
= tlink_execute ("ld", ld_argv
, ldout
);
620 /* Until collect does a better job of figuring out which are object
621 files, assume that everything on the command line could be. */
622 if (read_repo_files (ld_argv
))
623 while (exit
&& i
++ < MAX_ITERATIONS
)
625 if (tlink_verbose
>= 3)
627 demangle_new_symbols ();
628 if (! scan_linker_output (ldout
))
630 if (! recompile_files ())
633 fprintf (stderr
, "collect: relinking\n");
634 exit
= tlink_execute ("ld", ld_argv
, ldout
);
642 error ("ld returned %d exit status", exit
);