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. */
29 #define MAX_ITERATIONS 17
31 /* Obstack allocation and deallocation routines. */
32 #define obstack_chunk_alloc xmalloc
33 #define obstack_chunk_free free
35 extern char * xmalloc
PARAMS((unsigned));
37 extern char * getenv ();
39 /* Defined in collect2.c. */
40 extern int vflag
, debug
;
42 extern char *c_file_name
;
43 extern struct obstack temporary_obstack
;
44 extern struct obstack permanent_obstack
;
45 extern char * temporary_firstobj
;
47 /* Defined in the automatically-generated underscore.c. */
48 extern int prepends_underscore
;
50 static int tlink_verbose
;
52 /* Hash table code. */
54 typedef struct symbol_hash_entry
56 struct hash_entry root
;
57 struct file_hash_entry
*file
;
63 typedef struct file_hash_entry
65 struct hash_entry root
;
72 typedef struct demangled_hash_entry
74 struct hash_entry root
;
78 static struct hash_table symbol_table
;
80 static struct hash_entry
*
81 symbol_hash_newfunc (entry
, table
, string
)
82 struct hash_entry
*entry
;
83 struct hash_table
*table
;
86 struct symbol_hash_entry
*ret
= (struct symbol_hash_entry
*) entry
;
89 ret
= ((struct symbol_hash_entry
*)
90 hash_allocate (table
, sizeof (struct symbol_hash_entry
)));
94 ret
= ((struct symbol_hash_entry
*)
95 hash_newfunc ((struct hash_entry
*) ret
, table
, string
));
100 return (struct hash_entry
*) ret
;
103 static struct symbol_hash_entry
*
104 symbol_hash_lookup (string
, create
)
108 return ((struct symbol_hash_entry
*)
109 hash_lookup (&symbol_table
, string
, create
, true));
112 static struct hash_table file_table
;
114 static struct hash_entry
*
115 file_hash_newfunc (entry
, table
, string
)
116 struct hash_entry
*entry
;
117 struct hash_table
*table
;
120 struct file_hash_entry
*ret
= (struct file_hash_entry
*) entry
;
123 ret
= ((struct file_hash_entry
*)
124 hash_allocate (table
, sizeof (struct file_hash_entry
)));
128 ret
= ((struct file_hash_entry
*)
129 hash_newfunc ((struct hash_entry
*) ret
, table
, string
));
134 return (struct hash_entry
*) ret
;
137 static struct file_hash_entry
*
138 file_hash_lookup (string
)
141 return ((struct file_hash_entry
*)
142 hash_lookup (&file_table
, string
, true, 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
, string
));
164 return (struct hash_entry
*) ret
;
167 static struct demangled_hash_entry
*
168 demangled_hash_lookup (string
, create
)
172 return ((struct demangled_hash_entry
*)
173 hash_lookup (&demangled_table
, string
, create
, true));
178 struct symbol_stack_entry
181 struct symbol_stack_entry
*next
;
183 struct obstack symbol_stack_obstack
;
184 struct symbol_stack_entry
*symbol_stack
;
186 struct file_stack_entry
189 struct file_stack_entry
*next
;
191 struct obstack file_stack_obstack
;
192 struct file_stack_entry
*file_stack
;
198 struct symbol_stack_entry
*ep
= (struct symbol_stack_entry
*) obstack_alloc
199 (&symbol_stack_obstack
, sizeof (struct symbol_stack_entry
));
201 ep
->next
= symbol_stack
;
208 struct symbol_stack_entry
*ep
= symbol_stack
;
213 symbol_stack
= ep
->next
;
214 obstack_free (&symbol_stack_obstack
, ep
);
222 struct file_stack_entry
*ep
;
227 ep
= (struct file_stack_entry
*) obstack_alloc
228 (&file_stack_obstack
, sizeof (struct file_stack_entry
));
230 ep
->next
= file_stack
;
238 struct file_stack_entry
*ep
= file_stack
;
243 file_stack
= ep
->next
;
244 obstack_free (&file_stack_obstack
, ep
);
249 /* Other machinery. */
256 hash_table_init (&symbol_table
, symbol_hash_newfunc
);
257 hash_table_init (&file_table
, file_hash_newfunc
);
258 hash_table_init (&demangled_table
, demangled_hash_newfunc
);
259 obstack_begin (&symbol_stack_obstack
, 0);
260 obstack_begin (&file_stack_obstack
, 0);
262 p
= getenv ("TLINK_VERBOSE");
264 tlink_verbose
= atoi (p
);
276 tlink_execute (prog
, argv
, redir
)
281 collect_execute (prog
, argv
, redir
);
282 return collect_wait (prog
);
286 frob_extension (s
, ext
)
289 char *p
= (char *) rindex (s
, '/');
292 p
= (char *) rindex (p
, '.');
296 obstack_grow (&temporary_obstack
, s
, p
- s
);
297 return obstack_copy0 (&temporary_obstack
, ext
, strlen (ext
));
301 obstack_fgets (stream
, ob
)
306 while ((c
= getc (stream
)) != EOF
&& c
!= '\n')
307 obstack_1grow (ob
, c
);
308 if (obstack_object_size (ob
) == 0)
310 obstack_1grow (ob
, '\0');
311 return obstack_finish (ob
);
318 return obstack_fgets (stream
, &temporary_obstack
);
325 return obstack_fgets (stream
, &permanent_obstack
);
328 /* Real tlink code. */
331 freadsym (stream
, f
, chosen
)
339 char *name
= tfgets (stream
);
340 sym
= symbol_hash_lookup (name
, true);
343 if (sym
->file
== NULL
)
347 sym
->chosen
= chosen
;
351 if (sym
->chosen
&& sym
->file
!= f
)
353 if (sym
->chosen
== 1)
354 file_push (sym
->file
);
359 chosen
= sym
->chosen
;
363 sym
->chosen
= chosen
;
372 FILE *stream
= fopen (f
->root
.string
, "r");
374 if (tlink_verbose
>= 2)
375 fprintf (stderr
, "collect: reading %s\n", f
->root
.string
);
377 while (fscanf (stream
, "%c ", &c
) == 1)
382 f
->args
= pfgets (stream
);
385 f
->dir
= pfgets (stream
);
388 f
->main
= pfgets (stream
);
391 freadsym (stream
, f
, 2);
394 freadsym (stream
, f
, 1);
397 freadsym (stream
, f
, 0);
400 obstack_free (&temporary_obstack
, temporary_firstobj
);
404 f
->args
= getenv ("COLLECT_GCC_OPTIONS");
410 maybe_tweak (line
, f
)
414 symbol
*sym
= symbol_hash_lookup (line
+ 2, false);
416 if ((sym
->file
== f
&& sym
->tweaking
)
417 || (sym
->file
!= f
&& line
[0] == 'C'))
434 while ((f
= file_pop ()) != NULL
)
436 char *line
, *command
;
437 FILE *stream
= fopen (f
->root
.string
, "r");
438 char *outname
= frob_extension (f
->root
.string
, ".rnw");
439 FILE *output
= fopen (outname
, "w");
441 while ((line
= tfgets (stream
)) != NULL
)
447 maybe_tweak (line
, f
);
449 fprintf (output
, "%s\n", line
);
453 rename (outname
, f
->root
.string
);
455 obstack_grow (&temporary_obstack
, "cd ", 3);
456 obstack_grow (&temporary_obstack
, f
->dir
, strlen (f
->dir
));
457 obstack_grow (&temporary_obstack
, "; ", 2);
458 obstack_grow (&temporary_obstack
, c_file_name
, strlen (c_file_name
));
459 obstack_1grow (&temporary_obstack
, ' ');
460 obstack_grow (&temporary_obstack
, f
->args
, strlen (f
->args
));
461 obstack_1grow (&temporary_obstack
, ' ');
462 command
= obstack_copy0 (&temporary_obstack
, f
->main
, strlen (f
->main
));
465 fprintf (stderr
, "collect: recompiling %s\n", f
->main
);
466 if (tlink_verbose
>= 3)
467 fprintf (stderr
, "%s\n", command
);
469 if (system (command
) != 0)
474 obstack_free (&temporary_obstack
, temporary_firstobj
);
480 read_repo_files (object_lst
)
483 char **object
= object_lst
;
485 for (; *object
; object
++)
487 char *p
= frob_extension (*object
, ".rpo");
490 if (! file_exists (p
))
493 f
= file_hash_lookup (p
);
498 if (file_stack
!= NULL
&& ! recompile_files ())
501 return (symbol_stack
!= NULL
);
505 demangle_new_symbols ()
509 while ((sym
= symbol_pop ()) != NULL
)
512 char *p
= cplus_demangle (sym
->root
.string
, DMGL_PARAMS
| DMGL_ANSI
);
517 dem
= demangled_hash_lookup (p
, true);
518 dem
->mangled
= sym
->root
.string
;
523 scan_linker_output (fname
)
526 FILE *stream
= fopen (fname
, "r");
529 while ((line
= tfgets (stream
)) != NULL
)
535 while (*p
&& isspace (*p
))
541 for (q
= p
; *q
&& ! isspace (*q
); ++q
)
544 /* Try the first word on the line. */
547 if (*p
== '_' && prepends_underscore
)
552 sym
= symbol_hash_lookup (p
, false);
555 /* Try a mangled name in `quotes'. */
558 p
= (char *) index (q
+1, '`');
561 #define MUL "multiple definition of "
562 #define UND "undefined reference to "
564 if (p
&& (p
- line
> sizeof (MUL
)))
566 char *beg
= p
- sizeof (MUL
) + 1;
568 if (!strcmp (beg
, MUL
) || !strcmp (beg
, UND
))
569 p
++, q
= (char *) index (p
, '\'');
572 *q
= 0, dem
= demangled_hash_lookup (p
, false);
574 sym
= symbol_hash_lookup (dem
->mangled
, false);
577 if (sym
&& sym
->tweaked
)
582 if (sym
&& !sym
->tweaking
)
584 if (tlink_verbose
>= 2)
585 fprintf (stderr
, "collect: tweaking %s in %s\n",
586 sym
->root
.string
, sym
->file
->root
.string
);
588 file_push (sym
->file
);
591 obstack_free (&temporary_obstack
, temporary_firstobj
);
595 return (file_stack
!= NULL
);
599 do_tlink (ld_argv
, object_lst
)
600 char **ld_argv
, **object_lst
;
602 int exit
= tlink_execute ("ld", ld_argv
, ldout
);
610 /* Until collect does a better job of figuring out which are object
611 files, assume that everything on the command line could be. */
612 if (read_repo_files (ld_argv
))
613 while (exit
&& i
++ < MAX_ITERATIONS
)
615 if (tlink_verbose
>= 3)
617 demangle_new_symbols ();
618 if (! scan_linker_output (ldout
))
620 if (! recompile_files ())
623 fprintf (stderr
, "collect: relinking\n");
624 exit
= tlink_execute ("ld", ld_argv
, ldout
);
632 error ("ld returned %d exit status", exit
);