[official-gcc.git] / gcc / tlink.c
bloba4c5b5311cdabbbb42805df909286017d0912784
1 /* Scan linker error messages for missing template instantiations and provide
2 them.
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)
12 any later version.
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. */
23 #include "config.h"
24 #include "system.h"
25 #include "hash.h"
26 #include "demangle.h"
27 #include "toplev.h"
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 /* Defined in collect2.c. */
38 extern int vflag, debug;
39 extern char *ldout;
40 extern char *c_file_name;
41 extern struct obstack temporary_obstack;
42 extern struct obstack permanent_obstack;
43 extern char * temporary_firstobj;
45 /* Defined in the automatically-generated underscore.c. */
46 extern int prepends_underscore;
48 static int tlink_verbose;
50 /* Hash table code. */
52 typedef struct symbol_hash_entry
54 struct hash_entry root;
55 struct file_hash_entry *file;
56 int chosen;
57 int tweaking;
58 int tweaked;
59 } symbol;
61 typedef struct file_hash_entry
63 struct hash_entry root;
64 const char *args;
65 const char *dir;
66 const char *main;
67 int tweaking;
68 } file;
70 typedef struct demangled_hash_entry
72 struct hash_entry root;
73 const char *mangled;
74 } demangled;
76 static struct hash_table symbol_table;
78 static struct hash_entry *
79 symbol_hash_newfunc (entry, table, string)
80 struct hash_entry *entry;
81 struct hash_table *table;
82 const char *string;
84 struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry;
85 if (ret == NULL)
87 ret = ((struct symbol_hash_entry *)
88 hash_allocate (table, sizeof (struct symbol_hash_entry)));
89 if (ret == NULL)
90 return NULL;
92 ret = ((struct symbol_hash_entry *)
93 hash_newfunc ((struct hash_entry *) ret, table, string));
94 ret->file = NULL;
95 ret->chosen = 0;
96 ret->tweaking = 0;
97 ret->tweaked = 0;
98 return (struct hash_entry *) ret;
101 static struct symbol_hash_entry *
102 symbol_hash_lookup (string, create)
103 const char *string;
104 boolean create;
106 return ((struct symbol_hash_entry *)
107 hash_lookup (&symbol_table, string, create, true));
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;
116 const char *string;
118 struct file_hash_entry *ret = (struct file_hash_entry *) entry;
119 if (ret == NULL)
121 ret = ((struct file_hash_entry *)
122 hash_allocate (table, sizeof (struct file_hash_entry)));
123 if (ret == NULL)
124 return NULL;
126 ret = ((struct file_hash_entry *)
127 hash_newfunc ((struct hash_entry *) ret, table, string));
128 ret->args = NULL;
129 ret->dir = NULL;
130 ret->main = NULL;
131 ret->tweaking = 0;
132 return (struct hash_entry *) ret;
135 static struct file_hash_entry *
136 file_hash_lookup (string)
137 const char *string;
139 return ((struct file_hash_entry *)
140 hash_lookup (&file_table, string, true, true));
143 static struct hash_table demangled_table;
145 static struct hash_entry *
146 demangled_hash_newfunc (entry, table, string)
147 struct hash_entry *entry;
148 struct hash_table *table;
149 const char *string;
151 struct demangled_hash_entry *ret = (struct demangled_hash_entry *) entry;
152 if (ret == NULL)
154 ret = ((struct demangled_hash_entry *)
155 hash_allocate (table, sizeof (struct demangled_hash_entry)));
156 if (ret == NULL)
157 return NULL;
159 ret = ((struct demangled_hash_entry *)
160 hash_newfunc ((struct hash_entry *) ret, table, string));
161 ret->mangled = NULL;
162 return (struct hash_entry *) ret;
165 static struct demangled_hash_entry *
166 demangled_hash_lookup (string, create)
167 const char *string;
168 boolean create;
170 return ((struct demangled_hash_entry *)
171 hash_lookup (&demangled_table, string, create, true));
174 /* Stack code. */
176 struct symbol_stack_entry
178 symbol *value;
179 struct symbol_stack_entry *next;
181 struct obstack symbol_stack_obstack;
182 struct symbol_stack_entry *symbol_stack;
184 struct file_stack_entry
186 file *value;
187 struct file_stack_entry *next;
189 struct obstack file_stack_obstack;
190 struct file_stack_entry *file_stack;
192 static void
193 symbol_push (p)
194 symbol *p;
196 struct symbol_stack_entry *ep = (struct symbol_stack_entry *) obstack_alloc
197 (&symbol_stack_obstack, sizeof (struct symbol_stack_entry));
198 ep->value = p;
199 ep->next = symbol_stack;
200 symbol_stack = ep;
203 static symbol *
204 symbol_pop ()
206 struct symbol_stack_entry *ep = symbol_stack;
207 symbol *p;
208 if (ep == NULL)
209 return NULL;
210 p = ep->value;
211 symbol_stack = ep->next;
212 obstack_free (&symbol_stack_obstack, ep);
213 return p;
216 static void
217 file_push (p)
218 file *p;
220 struct file_stack_entry *ep;
222 if (p->tweaking)
223 return;
225 ep = (struct file_stack_entry *) obstack_alloc
226 (&file_stack_obstack, sizeof (struct file_stack_entry));
227 ep->value = p;
228 ep->next = file_stack;
229 file_stack = ep;
230 p->tweaking = 1;
233 static file *
234 file_pop ()
236 struct file_stack_entry *ep = file_stack;
237 file *p;
238 if (ep == NULL)
239 return NULL;
240 p = ep->value;
241 file_stack = ep->next;
242 obstack_free (&file_stack_obstack, ep);
243 p->tweaking = 0;
244 return p;
247 /* Other machinery. */
249 static void
250 tlink_init ()
252 char *p;
254 hash_table_init (&symbol_table, symbol_hash_newfunc);
255 hash_table_init (&file_table, file_hash_newfunc);
256 hash_table_init (&demangled_table, demangled_hash_newfunc);
257 obstack_begin (&symbol_stack_obstack, 0);
258 obstack_begin (&file_stack_obstack, 0);
260 p = getenv ("TLINK_VERBOSE");
261 if (p)
262 tlink_verbose = atoi (p);
263 else
265 tlink_verbose = 1;
266 if (vflag)
267 tlink_verbose = 2;
268 if (debug)
269 tlink_verbose = 3;
273 static int
274 tlink_execute (prog, argv, redir)
275 char *prog;
276 char **argv;
277 char *redir;
279 collect_execute (prog, argv, redir);
280 return collect_wait (prog);
283 static char *
284 frob_extension (s, ext)
285 char *s, *ext;
287 char *p = rindex (s, '/');
288 if (! p)
289 p = s;
290 p = rindex (p, '.');
291 if (! p)
292 p = s + strlen (s);
294 obstack_grow (&temporary_obstack, s, p - s);
295 return obstack_copy0 (&temporary_obstack, ext, strlen (ext));
298 static char *
299 obstack_fgets (stream, ob)
300 FILE *stream;
301 struct obstack *ob;
303 int c;
304 while ((c = getc (stream)) != EOF && c != '\n')
305 obstack_1grow (ob, c);
306 if (obstack_object_size (ob) == 0)
307 return NULL;
308 obstack_1grow (ob, '\0');
309 return obstack_finish (ob);
312 static char *
313 tfgets (stream)
314 FILE *stream;
316 return obstack_fgets (stream, &temporary_obstack);
319 static char *
320 pfgets (stream)
321 FILE *stream;
323 return obstack_fgets (stream, &permanent_obstack);
326 /* Real tlink code. */
328 static void
329 freadsym (stream, f, chosen)
330 FILE *stream;
331 file *f;
332 int chosen;
334 symbol *sym;
337 char *name = tfgets (stream);
338 sym = symbol_hash_lookup (name, true);
341 if (sym->file == NULL)
343 symbol_push (sym);
344 sym->file = f;
345 sym->chosen = chosen;
347 else if (chosen)
349 if (sym->chosen && sym->file != f)
351 if (sym->chosen == 1)
352 file_push (sym->file);
353 else
355 file_push (f);
356 f = sym->file;
357 chosen = sym->chosen;
360 sym->file = f;
361 sym->chosen = chosen;
365 static void
366 read_repo_file (f)
367 file *f;
369 char c;
370 FILE *stream = fopen (f->root.string, "r");
372 if (tlink_verbose >= 2)
373 fprintf (stderr, "collect: reading %s\n", f->root.string);
375 while (fscanf (stream, "%c ", &c) == 1)
377 switch (c)
379 case 'A':
380 f->args = pfgets (stream);
381 break;
382 case 'D':
383 f->dir = pfgets (stream);
384 break;
385 case 'M':
386 f->main = pfgets (stream);
387 break;
388 case 'P':
389 freadsym (stream, f, 2);
390 break;
391 case 'C':
392 freadsym (stream, f, 1);
393 break;
394 case 'O':
395 freadsym (stream, f, 0);
396 break;
398 obstack_free (&temporary_obstack, temporary_firstobj);
400 fclose (stream);
401 if (f->args == NULL)
402 f->args = getenv ("COLLECT_GCC_OPTIONS");
403 if (f->dir == NULL)
404 f->dir = ".";
407 static void
408 maybe_tweak (line, f)
409 char *line;
410 file *f;
412 symbol *sym = symbol_hash_lookup (line + 2, false);
414 if ((sym->file == f && sym->tweaking)
415 || (sym->file != f && line[0] == 'C'))
417 sym->tweaking = 0;
418 sym->tweaked = 1;
420 if (line[0] == 'O')
421 line[0] = 'C';
422 else
423 line[0] = 'O';
427 static int
428 recompile_files ()
430 file *f;
432 while ((f = file_pop ()) != NULL)
434 char *line, *command;
435 FILE *stream = fopen (f->root.string, "r");
436 char *outname = frob_extension (f->root.string, ".rnw");
437 FILE *output = fopen (outname, "w");
439 while ((line = tfgets (stream)) != NULL)
441 switch (line[0])
443 case 'C':
444 case 'O':
445 maybe_tweak (line, f);
447 fprintf (output, "%s\n", line);
449 fclose (stream);
450 fclose (output);
451 rename (outname, f->root.string);
453 obstack_grow (&temporary_obstack, "cd ", 3);
454 obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
455 obstack_grow (&temporary_obstack, "; ", 2);
456 obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name));
457 obstack_1grow (&temporary_obstack, ' ');
458 obstack_grow (&temporary_obstack, f->args, strlen (f->args));
459 obstack_1grow (&temporary_obstack, ' ');
460 command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main));
462 if (tlink_verbose)
463 fprintf (stderr, "collect: recompiling %s\n", f->main);
464 if (tlink_verbose >= 3)
465 fprintf (stderr, "%s\n", command);
467 if (system (command) != 0)
468 return 0;
470 read_repo_file (f);
472 obstack_free (&temporary_obstack, temporary_firstobj);
474 return 1;
477 static int
478 read_repo_files (object_lst)
479 char **object_lst;
481 char **object = object_lst;
483 for (; *object; object++)
485 char *p = frob_extension (*object, ".rpo");
486 file *f;
488 if (! file_exists (p))
489 continue;
491 f = file_hash_lookup (p);
493 read_repo_file (f);
496 if (file_stack != NULL && ! recompile_files ())
497 return 0;
499 return (symbol_stack != NULL);
502 static void
503 demangle_new_symbols ()
505 symbol *sym;
507 while ((sym = symbol_pop ()) != NULL)
509 demangled *dem;
510 char *p = cplus_demangle (sym->root.string, DMGL_PARAMS | DMGL_ANSI);
512 if (! p)
513 continue;
515 dem = demangled_hash_lookup (p, true);
516 dem->mangled = sym->root.string;
520 static int
521 scan_linker_output (fname)
522 char *fname;
524 FILE *stream = fopen (fname, "r");
525 char *line;
527 while ((line = tfgets (stream)) != NULL)
529 char *p = line, *q;
530 symbol *sym;
531 int end;
533 while (*p && ISSPACE (*p))
534 ++p;
536 if (! *p)
537 continue;
539 for (q = p; *q && ! ISSPACE (*q); ++q)
542 /* Try the first word on the line. */
543 if (*p == '.')
544 ++p;
545 if (*p == '_' && prepends_underscore)
546 ++p;
548 end = ! *q;
549 *q = 0;
550 sym = symbol_hash_lookup (p, false);
552 if (! sym && ! end)
553 /* Try a mangled name in quotes. */
555 char *oldq = q+1;
556 demangled *dem = 0;
557 q = 0;
559 /* First try `GNU style'. */
560 p = index (oldq, '`');
561 if (p)
562 p++, q = index (p, '\'');
563 /* Then try "double quotes". */
564 else if (p = index (oldq, '"'), p)
565 p++, q = index (p, '"');
567 if (q)
569 *q = 0;
570 dem = demangled_hash_lookup (p, false);
571 if (dem)
572 sym = symbol_hash_lookup (dem->mangled, false);
573 else
574 sym = symbol_hash_lookup (p, false);
578 if (sym && sym->tweaked)
580 fclose (stream);
581 return 0;
583 if (sym && !sym->tweaking)
585 if (tlink_verbose >= 2)
586 fprintf (stderr, "collect: tweaking %s in %s\n",
587 sym->root.string, sym->file->root.string);
588 sym->tweaking = 1;
589 file_push (sym->file);
592 obstack_free (&temporary_obstack, temporary_firstobj);
595 fclose (stream);
596 return (file_stack != NULL);
599 void
600 do_tlink (ld_argv, object_lst)
601 char **ld_argv, **object_lst;
603 int exit = tlink_execute ("ld", ld_argv, ldout);
605 tlink_init ();
607 if (exit)
609 int i = 0;
611 /* Until collect does a better job of figuring out which are object
612 files, assume that everything on the command line could be. */
613 if (read_repo_files (ld_argv))
614 while (exit && i++ < MAX_ITERATIONS)
616 if (tlink_verbose >= 3)
617 dump_file (ldout);
618 demangle_new_symbols ();
619 if (! scan_linker_output (ldout))
620 break;
621 if (! recompile_files ())
622 break;
623 if (tlink_verbose)
624 fprintf (stderr, "collect: relinking\n");
625 exit = tlink_execute ("ld", ld_argv, ldout);
629 dump_file (ldout);
630 unlink (ldout);
631 if (exit)
633 error ("ld returned %d exit status", exit);
634 collect_exit (exit);