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);