1 /* Scan linker error messages for missing template instantiations and provide
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)
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 /* Defined in collect2.c. */
36 extern int vflag, debug;
38 extern char *c_file_name;
39 extern struct obstack temporary_obstack;
40 extern struct obstack permanent_obstack;
41 extern char * temporary_firstobj;
43 /* Defined in the automatically-generated underscore.c. */
44 extern int prepends_underscore;
46 static int tlink_verbose;
48 /* Hash table code. */
50 typedef struct symbol_hash_entry
52 struct hash_entry root;
53 struct file_hash_entry *file;
59 typedef struct file_hash_entry
61 struct hash_entry root;
68 typedef struct demangled_hash_entry
70 struct hash_entry root;
74 static struct hash_table symbol_table;
76 static struct hash_entry *
77 symbol_hash_newfunc (entry, table, string)
78 struct hash_entry *entry;
79 struct hash_table *table;
82 struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry;
85 ret = ((struct symbol_hash_entry *)
86 hash_allocate (table, sizeof (struct symbol_hash_entry)));
90 ret = ((struct symbol_hash_entry *)
91 hash_newfunc ((struct hash_entry *) ret, table,
92 (hash_table_key) string));
97 return (struct hash_entry *) ret;
100 static struct symbol_hash_entry *
101 symbol_hash_lookup (string, create)
105 return ((struct symbol_hash_entry *)
106 hash_lookup (&symbol_table, (hash_table_key) string,
107 create, &string_copy));
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;
118 struct file_hash_entry *ret = (struct file_hash_entry *) entry;
121 ret = ((struct file_hash_entry *)
122 hash_allocate (table, sizeof (struct file_hash_entry)));
126 ret = ((struct file_hash_entry *)
127 hash_newfunc ((struct hash_entry *) ret, table,
128 (hash_table_key) string));
133 return (struct hash_entry *) ret;
136 static struct file_hash_entry *
137 file_hash_lookup (string)
140 return ((struct file_hash_entry *)
141 hash_lookup (&file_table, (hash_table_key) string, 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,
163 (hash_table_key) 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, (hash_table_key) string,
175 create, &string_copy));
180 struct symbol_stack_entry
183 struct symbol_stack_entry *next;
185 struct obstack symbol_stack_obstack;
186 struct symbol_stack_entry *symbol_stack;
188 struct file_stack_entry
191 struct file_stack_entry *next;
193 struct obstack file_stack_obstack;
194 struct file_stack_entry *file_stack;
200 struct symbol_stack_entry *ep = (struct symbol_stack_entry *) obstack_alloc
201 (&symbol_stack_obstack, sizeof (struct symbol_stack_entry));
203 ep->next = symbol_stack;
210 struct symbol_stack_entry *ep = symbol_stack;
215 symbol_stack = ep->next;
216 obstack_free (&symbol_stack_obstack, ep);
224 struct file_stack_entry *ep;
229 ep = (struct file_stack_entry *) obstack_alloc
230 (&file_stack_obstack, sizeof (struct file_stack_entry));
232 ep->next = file_stack;
240 struct file_stack_entry *ep = file_stack;
245 file_stack = ep->next;
246 obstack_free (&file_stack_obstack, ep);
251 /* Other machinery. */
258 hash_table_init (&symbol_table, symbol_hash_newfunc, &string_hash,
260 hash_table_init (&file_table, file_hash_newfunc, &string_hash,
262 hash_table_init (&demangled_table, demangled_hash_newfunc,
263 &string_hash, &string_compare);
264 obstack_begin (&symbol_stack_obstack, 0);
265 obstack_begin (&file_stack_obstack, 0);
267 p = getenv ("TLINK_VERBOSE");
269 tlink_verbose = atoi (p);
281 tlink_execute (prog, argv, redir)
286 collect_execute (prog, argv, redir);
287 return collect_wait (prog);
291 frob_extension (s, ext)
294 char *p = rindex (s, '/');
301 obstack_grow (&temporary_obstack, s, p - s);
302 return obstack_copy0 (&temporary_obstack, ext, strlen (ext));
306 obstack_fgets (stream, ob)
311 while ((c = getc (stream)) != EOF && c != '\n')
312 obstack_1grow (ob, c);
313 if (obstack_object_size (ob) == 0)
315 obstack_1grow (ob, '\0');
316 return obstack_finish (ob);
323 return obstack_fgets (stream, &temporary_obstack);
330 return obstack_fgets (stream, &permanent_obstack);
333 /* Real tlink code. */
336 freadsym (stream, f, chosen)
344 char *name = tfgets (stream);
345 sym = symbol_hash_lookup (name, true);
348 if (sym->file == NULL)
352 sym->chosen = chosen;
356 if (sym->chosen && sym->file != f)
358 if (sym->chosen == 1)
359 file_push (sym->file);
364 chosen = sym->chosen;
368 sym->chosen = chosen;
377 FILE *stream = fopen ((char*) f->root.key, "r");
379 if (tlink_verbose >= 2)
380 fprintf (stderr, "collect: reading %s\n",
381 (char*) f->root.key);
383 while (fscanf (stream, "%c ", &c) == 1)
388 f->args = pfgets (stream);
391 f->dir = pfgets (stream);
394 f->main = pfgets (stream);
397 freadsym (stream, f, 2);
400 freadsym (stream, f, 1);
403 freadsym (stream, f, 0);
406 obstack_free (&temporary_obstack, temporary_firstobj);
410 f->args = getenv ("COLLECT_GCC_OPTIONS");
416 maybe_tweak (line, f)
420 symbol *sym = symbol_hash_lookup (line + 2, false);
422 if ((sym->file == f && sym->tweaking)
423 || (sym->file != f && line[0] == 'C'))
440 while ((f = file_pop ()) != NULL)
442 char *line, *command;
443 FILE *stream = fopen ((char*) f->root.key, "r");
444 char *outname = frob_extension ((char*) f->root.key, ".rnw");
445 FILE *output = fopen (outname, "w");
447 while ((line = tfgets (stream)) != NULL)
453 maybe_tweak (line, f);
455 fprintf (output, "%s\n", line);
459 rename (outname, (char*) f->root.key);
461 obstack_grow (&temporary_obstack, "cd ", 3);
462 obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
463 obstack_grow (&temporary_obstack, "; ", 2);
464 obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name));
465 obstack_1grow (&temporary_obstack, ' ');
466 obstack_grow (&temporary_obstack, f->args, strlen (f->args));
467 obstack_1grow (&temporary_obstack, ' ');
468 command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main));
471 fprintf (stderr, "collect: recompiling %s\n", f->main);
472 if (tlink_verbose >= 3)
473 fprintf (stderr, "%s\n", command);
475 if (system (command) != 0)
480 obstack_free (&temporary_obstack, temporary_firstobj);
486 read_repo_files (object_lst)
489 char **object = object_lst;
491 for (; *object; object++)
493 char *p = frob_extension (*object, ".rpo");
496 if (! file_exists (p))
499 f = file_hash_lookup (p);
504 if (file_stack != NULL && ! recompile_files ())
507 return (symbol_stack != NULL);
511 demangle_new_symbols ()
515 while ((sym = symbol_pop ()) != NULL)
518 char *p = cplus_demangle ((char*) sym->root.key,
519 DMGL_PARAMS | DMGL_ANSI);
524 dem = demangled_hash_lookup (p, true);
525 dem->mangled = (char*) sym->root.key;
530 scan_linker_output (fname)
533 FILE *stream = fopen (fname, "r");
536 while ((line = tfgets (stream)) != NULL)
542 while (*p && ISSPACE ((unsigned char)*p))
548 for (q = p; *q && ! ISSPACE ((unsigned char)*q); ++q)
551 /* Try the first word on the line. */
554 if (*p == '_' && prepends_underscore)
559 sym = symbol_hash_lookup (p, false);
562 /* Try a mangled name in quotes. */
568 /* First try `GNU style'. */
569 p = index (oldq, '`');
571 p++, q = index (p, '\'');
572 /* Then try "double quotes". */
573 else if (p = index (oldq, '"'), p)
574 p++, q = index (p, '"');
579 dem = demangled_hash_lookup (p, false);
581 sym = symbol_hash_lookup (dem->mangled, false);
583 sym = symbol_hash_lookup (p, false);
587 if (sym && sym->tweaked)
592 if (sym && !sym->tweaking)
594 if (tlink_verbose >= 2)
595 fprintf (stderr, "collect: tweaking %s in %s\n",
596 (char*) sym->root.key, (char*) sym->file->root.key);
598 file_push (sym->file);
601 obstack_free (&temporary_obstack, temporary_firstobj);
605 return (file_stack != NULL);
609 do_tlink (ld_argv, object_lst)
610 char **ld_argv, **object_lst;
612 int exit = tlink_execute ("ld", ld_argv, ldout);
620 /* Until collect does a better job of figuring out which are object
621 files, assume that everything on the command line could be. */
622 if (read_repo_files (ld_argv))
623 while (exit && i++ < MAX_ITERATIONS)
625 if (tlink_verbose >= 3)
627 demangle_new_symbols ();
628 if (! scan_linker_output (ldout))
630 if (! recompile_files ())
633 fprintf (stderr, "collect: relinking\n");
634 exit = tlink_execute ("ld", ld_argv, ldout);
642 error ("ld returned %d exit status", exit);