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