1 /* Scan linker error messages for missing template instantiations and provide
4 Copyright (C) 1995 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. */
45 #define MAX_ITERATIONS 17
47 /* Obstack allocation and deallocation routines. */
48 #define obstack_chunk_alloc xmalloc
49 #define obstack_chunk_free free
51 extern char * xmalloc
PARAMS((unsigned));
53 extern char * getenv ();
55 /* Defined in collect2.c. */
56 extern int vflag
, debug
;
58 extern char *c_file_name
;
59 extern struct obstack temporary_obstack
;
60 extern struct obstack permanent_obstack
;
61 extern char * temporary_firstobj
;
63 /* Defined in the automatically-generated underscore.c. */
64 extern int prepends_underscore
;
66 static int tlink_verbose
;
68 /* Hash table code. */
70 typedef struct symbol_hash_entry
72 struct hash_entry root
;
73 struct file_hash_entry
*file
;
79 typedef struct file_hash_entry
81 struct hash_entry root
;
88 typedef struct demangled_hash_entry
90 struct hash_entry root
;
94 static struct hash_table symbol_table
;
96 static struct hash_entry
*
97 symbol_hash_newfunc (entry
, table
, string
)
98 struct hash_entry
*entry
;
99 struct hash_table
*table
;
102 struct symbol_hash_entry
*ret
= (struct symbol_hash_entry
*) entry
;
105 ret
= ((struct symbol_hash_entry
*)
106 hash_allocate (table
, sizeof (struct symbol_hash_entry
)));
110 ret
= ((struct symbol_hash_entry
*)
111 hash_newfunc ((struct hash_entry
*) ret
, table
, string
));
116 return (struct hash_entry
*) ret
;
119 static struct symbol_hash_entry
*
120 symbol_hash_lookup (string
, create
)
124 return ((struct symbol_hash_entry
*)
125 hash_lookup (&symbol_table
, string
, create
, true));
128 static struct hash_table file_table
;
130 static struct hash_entry
*
131 file_hash_newfunc (entry
, table
, string
)
132 struct hash_entry
*entry
;
133 struct hash_table
*table
;
136 struct file_hash_entry
*ret
= (struct file_hash_entry
*) entry
;
139 ret
= ((struct file_hash_entry
*)
140 hash_allocate (table
, sizeof (struct file_hash_entry
)));
144 ret
= ((struct file_hash_entry
*)
145 hash_newfunc ((struct hash_entry
*) ret
, table
, string
));
150 return (struct hash_entry
*) ret
;
153 static struct file_hash_entry
*
154 file_hash_lookup (string
)
157 return ((struct file_hash_entry
*)
158 hash_lookup (&file_table
, string
, true, true));
161 static struct hash_table demangled_table
;
163 static struct hash_entry
*
164 demangled_hash_newfunc (entry
, table
, string
)
165 struct hash_entry
*entry
;
166 struct hash_table
*table
;
169 struct demangled_hash_entry
*ret
= (struct demangled_hash_entry
*) entry
;
172 ret
= ((struct demangled_hash_entry
*)
173 hash_allocate (table
, sizeof (struct demangled_hash_entry
)));
177 ret
= ((struct demangled_hash_entry
*)
178 hash_newfunc ((struct hash_entry
*) ret
, table
, string
));
180 return (struct hash_entry
*) ret
;
183 static struct demangled_hash_entry
*
184 demangled_hash_lookup (string
, create
)
188 return ((struct demangled_hash_entry
*)
189 hash_lookup (&demangled_table
, string
, create
, true));
194 struct symbol_stack_entry
197 struct symbol_stack_entry
*next
;
199 struct obstack symbol_stack_obstack
;
200 struct symbol_stack_entry
*symbol_stack
;
202 struct file_stack_entry
205 struct file_stack_entry
*next
;
207 struct obstack file_stack_obstack
;
208 struct file_stack_entry
*file_stack
;
214 struct symbol_stack_entry
*ep
= (struct symbol_stack_entry
*) obstack_alloc
215 (&symbol_stack_obstack
, sizeof (struct symbol_stack_entry
));
217 ep
->next
= symbol_stack
;
224 struct symbol_stack_entry
*ep
= symbol_stack
;
229 symbol_stack
= ep
->next
;
230 obstack_free (&symbol_stack_obstack
, ep
);
238 struct file_stack_entry
*ep
;
243 ep
= (struct file_stack_entry
*) obstack_alloc
244 (&file_stack_obstack
, sizeof (struct file_stack_entry
));
246 ep
->next
= file_stack
;
254 struct file_stack_entry
*ep
= file_stack
;
259 file_stack
= ep
->next
;
260 obstack_free (&file_stack_obstack
, ep
);
265 /* Other machinery. */
272 hash_table_init (&symbol_table
, symbol_hash_newfunc
);
273 hash_table_init (&file_table
, file_hash_newfunc
);
274 hash_table_init (&demangled_table
, demangled_hash_newfunc
);
275 obstack_begin (&symbol_stack_obstack
, 0);
276 obstack_begin (&file_stack_obstack
, 0);
278 p
= getenv ("TLINK_VERBOSE");
280 tlink_verbose
= atoi (p
);
292 tlink_execute (prog
, argv
, redir
)
297 collect_execute (prog
, argv
, redir
);
298 return collect_wait (prog
);
302 frob_extension (s
, ext
)
305 char *p
= (char *) rindex (s
, '/');
308 p
= (char *) rindex (p
, '.');
312 obstack_grow (&temporary_obstack
, s
, p
- s
);
313 return obstack_copy0 (&temporary_obstack
, ext
, strlen (ext
));
317 obstack_fgets (stream
, ob
)
322 while ((c
= getc (stream
)) != EOF
&& c
!= '\n')
323 obstack_1grow (ob
, c
);
324 if (obstack_object_size (ob
) == 0)
326 obstack_1grow (ob
, '\0');
327 return obstack_finish (ob
);
334 return obstack_fgets (stream
, &temporary_obstack
);
341 return obstack_fgets (stream
, &permanent_obstack
);
344 /* Real tlink code. */
347 freadsym (stream
, f
, chosen
)
355 char *name
= tfgets (stream
);
356 sym
= symbol_hash_lookup (name
, true);
359 if (sym
->file
== NULL
)
363 sym
->chosen
= chosen
;
367 if (sym
->chosen
&& sym
->file
!= f
)
369 if (sym
->chosen
== 1)
370 file_push (sym
->file
);
375 chosen
= sym
->chosen
;
379 sym
->chosen
= chosen
;
388 FILE *stream
= fopen (f
->root
.string
, "r");
390 if (tlink_verbose
>= 2)
391 fprintf (stderr
, "collect: reading %s\n", f
->root
.string
);
393 while (fscanf (stream
, "%c ", &c
) == 1)
398 f
->args
= pfgets (stream
);
401 f
->dir
= pfgets (stream
);
404 f
->main
= pfgets (stream
);
407 freadsym (stream
, f
, 2);
410 freadsym (stream
, f
, 1);
413 freadsym (stream
, f
, 0);
416 obstack_free (&temporary_obstack
, temporary_firstobj
);
420 f
->args
= getenv ("COLLECT_GCC_OPTIONS");
426 maybe_tweak (line
, f
)
430 symbol
*sym
= symbol_hash_lookup (line
+ 2, false);
432 if ((sym
->file
== f
&& sym
->tweaking
)
433 || (sym
->file
!= f
&& line
[0] == 'C'))
450 while ((f
= file_pop ()) != NULL
)
452 char *line
, *command
;
453 FILE *stream
= fopen (f
->root
.string
, "r");
454 char *outname
= frob_extension (f
->root
.string
, ".rnw");
455 FILE *output
= fopen (outname
, "w");
457 while ((line
= tfgets (stream
)) != NULL
)
463 maybe_tweak (line
, f
);
465 fprintf (output
, "%s\n", line
);
469 rename (outname
, f
->root
.string
);
471 obstack_grow (&temporary_obstack
, "cd ", 3);
472 obstack_grow (&temporary_obstack
, f
->dir
, strlen (f
->dir
));
473 obstack_grow (&temporary_obstack
, "; ", 2);
474 obstack_grow (&temporary_obstack
, c_file_name
, strlen (c_file_name
));
475 obstack_1grow (&temporary_obstack
, ' ');
476 obstack_grow (&temporary_obstack
, f
->args
, strlen (f
->args
));
477 obstack_1grow (&temporary_obstack
, ' ');
478 command
= obstack_copy0 (&temporary_obstack
, f
->main
, strlen (f
->main
));
481 fprintf (stderr
, "collect: recompiling %s\n", f
->main
);
482 if (tlink_verbose
>= 3)
483 fprintf (stderr
, "%s\n", command
);
485 if (system (command
) != 0)
490 obstack_free (&temporary_obstack
, temporary_firstobj
);
496 read_repo_files (object_lst
)
499 char **object
= object_lst
;
501 for (; *object
; object
++)
503 char *p
= frob_extension (*object
, ".rpo");
506 if (! file_exists (p
))
509 f
= file_hash_lookup (p
);
514 if (file_stack
!= NULL
&& ! recompile_files ())
517 return (symbol_stack
!= NULL
);
521 demangle_new_symbols ()
525 while ((sym
= symbol_pop ()) != NULL
)
528 char *p
= cplus_demangle (sym
->root
.string
, DMGL_PARAMS
| DMGL_ANSI
);
533 dem
= demangled_hash_lookup (p
, true);
534 dem
->mangled
= sym
->root
.string
;
539 scan_linker_output (fname
)
542 FILE *stream
= fopen (fname
, "r");
545 while ((line
= tfgets (stream
)) != NULL
)
551 while (*p
&& isspace (*p
))
557 for (q
= p
; *q
&& ! isspace (*q
); ++q
)
560 /* Try the first word on the line. */
563 if (*p
== '_' && prepends_underscore
)
568 sym
= symbol_hash_lookup (p
, false);
571 /* Try a mangled name in `quotes'. */
574 p
= (char *) index (q
+1, '`');
577 #define MUL "multiple definition of "
578 #define UND "undefined reference to "
580 if (p
&& (p
- line
> sizeof (MUL
)))
582 char *beg
= p
- sizeof (MUL
) + 1;
584 if (!strcmp (beg
, MUL
) || !strcmp (beg
, UND
))
585 p
++, q
= (char *) index (p
, '\'');
588 *q
= 0, dem
= demangled_hash_lookup (p
, false);
590 sym
= symbol_hash_lookup (dem
->mangled
, false);
593 if (sym
&& sym
->tweaked
)
598 if (sym
&& !sym
->tweaking
)
600 if (tlink_verbose
>= 2)
601 fprintf (stderr
, "collect: tweaking %s in %s\n",
602 sym
->root
.string
, sym
->file
->root
.string
);
604 file_push (sym
->file
);
607 obstack_free (&temporary_obstack
, temporary_firstobj
);
611 return (file_stack
!= NULL
);
615 do_tlink (ld_argv
, object_lst
)
616 char **ld_argv
, **object_lst
;
618 int exit
= tlink_execute ("ld", ld_argv
, ldout
);
626 /* Until collect does a better job of figuring out which are object
627 files, assume that everything on the command line could be. */
628 if (read_repo_files (ld_argv
))
629 while (exit
&& i
++ < MAX_ITERATIONS
)
631 if (tlink_verbose
>= 3)
633 demangle_new_symbols ();
634 if (! scan_linker_output (ldout
))
636 if (! recompile_files ())
639 fprintf (stderr
, "collect: relinking\n");
640 exit
= tlink_execute ("ld", ld_argv
, ldout
);
648 error ("ld returned %d exit status", exit
);