1 /* CYGNUS LOCAL: whole file jason */
2 /* Scan linker error messages for missing template instantiations and provide
5 Copyright (C) 1995 Free Software Foundation, Inc.
6 Contributed by Jason Merrill (jason@cygnus.com).
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 extern char * xmalloc PARAMS((unsigned));
38 extern char * getenv ();
40 /* Defined in collect2.c. */
41 extern int vflag, debug;
43 extern char *c_file_name;
44 extern struct obstack temporary_obstack;
45 extern struct obstack permanent_obstack;
46 extern char * temporary_firstobj;
48 /* Defined in the automatically-generated underscore.c. */
49 extern int prepends_underscore;
51 static int tlink_verbose;
53 /* Hash table code. */
55 typedef struct symbol_hash_entry
57 struct hash_entry root;
58 struct file_hash_entry *file;
64 typedef struct file_hash_entry
66 struct hash_entry root;
73 typedef struct demangled_hash_entry
75 struct hash_entry root;
79 static struct hash_table symbol_table;
81 static struct hash_entry *
82 symbol_hash_newfunc (entry, table, string)
83 struct hash_entry *entry;
84 struct hash_table *table;
87 struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry;
90 ret = ((struct symbol_hash_entry *)
91 hash_allocate (table, sizeof (struct symbol_hash_entry)));
95 ret = ((struct symbol_hash_entry *)
96 hash_newfunc ((struct hash_entry *) ret, table, string));
101 return (struct hash_entry *) ret;
104 static struct symbol_hash_entry *
105 symbol_hash_lookup (string, create)
109 return ((struct symbol_hash_entry *)
110 hash_lookup (&symbol_table, string, create, true));
113 static struct hash_table file_table;
115 static struct hash_entry *
116 file_hash_newfunc (entry, table, string)
117 struct hash_entry *entry;
118 struct hash_table *table;
121 struct file_hash_entry *ret = (struct file_hash_entry *) entry;
124 ret = ((struct file_hash_entry *)
125 hash_allocate (table, sizeof (struct file_hash_entry)));
129 ret = ((struct file_hash_entry *)
130 hash_newfunc ((struct hash_entry *) ret, table, string));
135 return (struct hash_entry *) ret;
138 static struct file_hash_entry *
139 file_hash_lookup (string)
142 return ((struct file_hash_entry *)
143 hash_lookup (&file_table, string, true, true));
146 static struct hash_table demangled_table;
148 static struct hash_entry *
149 demangled_hash_newfunc (entry, table, string)
150 struct hash_entry *entry;
151 struct hash_table *table;
154 struct demangled_hash_entry *ret = (struct demangled_hash_entry *) entry;
157 ret = ((struct demangled_hash_entry *)
158 hash_allocate (table, sizeof (struct demangled_hash_entry)));
162 ret = ((struct demangled_hash_entry *)
163 hash_newfunc ((struct hash_entry *) ret, table, 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, string, create, true));
179 struct symbol_stack_entry
182 struct symbol_stack_entry *next;
184 struct obstack symbol_stack_obstack;
185 struct symbol_stack_entry *symbol_stack;
187 struct file_stack_entry
190 struct file_stack_entry *next;
192 struct obstack file_stack_obstack;
193 struct file_stack_entry *file_stack;
199 struct symbol_stack_entry *ep = (struct symbol_stack_entry *) obstack_alloc
200 (&symbol_stack_obstack, sizeof (struct symbol_stack_entry));
202 ep->next = symbol_stack;
209 struct symbol_stack_entry *ep = symbol_stack;
214 symbol_stack = ep->next;
215 obstack_free (&symbol_stack_obstack, ep);
223 struct file_stack_entry *ep;
228 ep = (struct file_stack_entry *) obstack_alloc
229 (&file_stack_obstack, sizeof (struct file_stack_entry));
231 ep->next = file_stack;
239 struct file_stack_entry *ep = file_stack;
244 file_stack = ep->next;
245 obstack_free (&file_stack_obstack, ep);
250 /* Other machinery. */
257 hash_table_init (&symbol_table, symbol_hash_newfunc);
258 hash_table_init (&file_table, file_hash_newfunc);
259 hash_table_init (&demangled_table, demangled_hash_newfunc);
260 obstack_begin (&symbol_stack_obstack, 0);
261 obstack_begin (&file_stack_obstack, 0);
263 p = getenv ("TLINK_VERBOSE");
265 tlink_verbose = atoi (p);
277 tlink_execute (prog, argv, redir)
282 collect_execute (prog, argv, redir);
283 return collect_wait (prog);
287 frob_extension (s, ext)
290 char *p = (char *) rindex (s, '/');
293 p = (char *) rindex (p, '.');
297 obstack_grow (&temporary_obstack, s, p - s);
298 return obstack_copy0 (&temporary_obstack, ext, strlen (ext));
302 obstack_fgets (stream, ob)
307 while ((c = getc (stream)) != EOF && c != '\n')
308 obstack_1grow (ob, c);
309 if (obstack_object_size (ob) == 0)
311 obstack_1grow (ob, '\0');
312 return obstack_finish (ob);
319 return obstack_fgets (stream, &temporary_obstack);
326 return obstack_fgets (stream, &permanent_obstack);
329 /* Real tlink code. */
332 freadsym (stream, f, chosen)
340 char *name = tfgets (stream);
341 sym = symbol_hash_lookup (name, true);
344 if (sym->file == NULL)
348 sym->chosen = chosen;
352 if (sym->chosen && sym->file != f)
354 if (sym->chosen == 1)
355 file_push (sym->file);
360 chosen = sym->chosen;
364 sym->chosen = chosen;
373 FILE *stream = fopen (f->root.string, "r");
375 if (tlink_verbose >= 2)
376 fprintf (stderr, "collect: reading %s\n", f->root.string);
378 while (fscanf (stream, "%c ", &c) == 1)
383 f->args = pfgets (stream);
386 f->dir = pfgets (stream);
389 f->main = pfgets (stream);
392 freadsym (stream, f, 2);
395 freadsym (stream, f, 1);
398 freadsym (stream, f, 0);
401 obstack_free (&temporary_obstack, temporary_firstobj);
405 f->args = getenv ("COLLECT_GCC_OPTIONS");
411 maybe_tweak (line, f)
415 symbol *sym = symbol_hash_lookup (line + 2, false);
417 if ((sym->file == f && sym->tweaking)
418 || (sym->file != f && line[0] == 'C'))
435 while ((f = file_pop ()) != NULL)
437 char *line, *command;
438 FILE *stream = fopen (f->root.string, "r");
439 char *outname = frob_extension (f->root.string, ".rnw");
440 FILE *output = fopen (outname, "w");
442 while ((line = tfgets (stream)) != NULL)
448 maybe_tweak (line, f);
450 fprintf (output, "%s\n", line);
454 rename (outname, f->root.string);
456 obstack_grow (&temporary_obstack, "cd ", 3);
457 obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
458 obstack_grow (&temporary_obstack, "; ", 2);
459 obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name));
460 obstack_1grow (&temporary_obstack, ' ');
461 obstack_grow (&temporary_obstack, f->args, strlen (f->args));
462 obstack_1grow (&temporary_obstack, ' ');
463 command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main));
466 fprintf (stderr, "collect: recompiling %s\n", f->main);
467 if (tlink_verbose >= 3)
468 fprintf (stderr, "%s\n", command);
470 if (system (command) != 0)
475 obstack_free (&temporary_obstack, temporary_firstobj);
481 read_repo_files (object_lst)
484 char **object = object_lst;
486 for (; *object; object++)
488 char *p = frob_extension (*object, ".rpo");
491 if (! file_exists (p))
494 f = file_hash_lookup (p);
499 if (file_stack != NULL && ! recompile_files ())
502 return (symbol_stack != NULL);
506 demangle_new_symbols ()
510 while ((sym = symbol_pop ()) != NULL)
513 char *p = cplus_demangle (sym->root.string, DMGL_PARAMS | DMGL_ANSI);
518 dem = demangled_hash_lookup (p, true);
519 dem->mangled = sym->root.string;
524 scan_linker_output (fname)
527 FILE *stream = fopen (fname, "r");
530 while ((line = tfgets (stream)) != NULL)
536 while (*p && isspace (*p))
542 for (q = p; *q && ! isspace (*q); ++q)
545 /* Try the first word on the line. */
548 if (*p == '_' && prepends_underscore)
553 sym = symbol_hash_lookup (p, false);
556 /* Try a mangled name in `quotes'. */
559 p = (char *) index (q+1, '`');
562 #define MUL "multiple definition of "
563 #define UND "undefined reference to "
565 if (p && (p - line > sizeof (MUL)))
567 char *beg = p - sizeof (MUL) + 1;
569 if (!strcmp (beg, MUL) || !strcmp (beg, UND))
570 p++, q = (char *) index (p, '\'');
573 *q = 0, dem = demangled_hash_lookup (p, false);
575 sym = symbol_hash_lookup (dem->mangled, false);
578 if (sym && sym->tweaked)
580 if (sym && !sym->tweaking)
582 if (tlink_verbose >= 2)
583 fprintf (stderr, "collect: tweaking %s in %s\n",
584 sym->root.string, sym->file->root.string);
586 file_push (sym->file);
589 obstack_free (&temporary_obstack, temporary_firstobj);
592 return (file_stack != NULL);
596 do_tlink (ld_argv, object_lst)
597 char **ld_argv, **object_lst;
599 int exit = tlink_execute ("ld", ld_argv, ldout);
607 /* Until collect does a better job of figuring out which are object
608 files, assume that everything on the command line could be. */
609 if (read_repo_files (ld_argv))
610 while (exit && i++ < MAX_ITERATIONS)
612 if (tlink_verbose >= 3)
614 demangle_new_symbols ();
615 if (! scan_linker_output (ldout))
617 if (! recompile_files ())
620 fprintf (stderr, "collect: relinking\n");
621 exit = tlink_execute ("ld", ld_argv, ldout);
629 error ("ld returned %d exit status", exit);