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 extern char * xmalloc PARAMS((unsigned));
37 /* Defined in collect2.c. */
38 extern int vflag, debug;
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;
61 typedef struct file_hash_entry
63 struct hash_entry root;
70 typedef struct demangled_hash_entry
72 struct hash_entry root;
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;
84 struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry;
87 ret = ((struct symbol_hash_entry *)
88 hash_allocate (table, sizeof (struct symbol_hash_entry)));
92 ret = ((struct symbol_hash_entry *)
93 hash_newfunc ((struct hash_entry *) ret, table, string));
98 return (struct hash_entry *) ret;
101 static struct symbol_hash_entry *
102 symbol_hash_lookup (string, 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;
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, string));
132 return (struct hash_entry *) ret;
135 static struct file_hash_entry *
136 file_hash_lookup (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;
151 struct demangled_hash_entry *ret = (struct demangled_hash_entry *) entry;
154 ret = ((struct demangled_hash_entry *)
155 hash_allocate (table, sizeof (struct demangled_hash_entry)));
159 ret = ((struct demangled_hash_entry *)
160 hash_newfunc ((struct hash_entry *) ret, table, string));
162 return (struct hash_entry *) ret;
165 static struct demangled_hash_entry *
166 demangled_hash_lookup (string, create)
170 return ((struct demangled_hash_entry *)
171 hash_lookup (&demangled_table, string, create, true));
176 struct symbol_stack_entry
179 struct symbol_stack_entry *next;
181 struct obstack symbol_stack_obstack;
182 struct symbol_stack_entry *symbol_stack;
184 struct file_stack_entry
187 struct file_stack_entry *next;
189 struct obstack file_stack_obstack;
190 struct file_stack_entry *file_stack;
196 struct symbol_stack_entry *ep = (struct symbol_stack_entry *) obstack_alloc
197 (&symbol_stack_obstack, sizeof (struct symbol_stack_entry));
199 ep->next = symbol_stack;
206 struct symbol_stack_entry *ep = symbol_stack;
211 symbol_stack = ep->next;
212 obstack_free (&symbol_stack_obstack, ep);
220 struct file_stack_entry *ep;
225 ep = (struct file_stack_entry *) obstack_alloc
226 (&file_stack_obstack, sizeof (struct file_stack_entry));
228 ep->next = file_stack;
236 struct file_stack_entry *ep = file_stack;
241 file_stack = ep->next;
242 obstack_free (&file_stack_obstack, ep);
247 /* Other machinery. */
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");
262 tlink_verbose = atoi (p);
274 tlink_execute (prog, argv, redir)
279 collect_execute (prog, argv, redir);
280 return collect_wait (prog);
284 frob_extension (s, ext)
287 char *p = rindex (s, '/');
294 obstack_grow (&temporary_obstack, s, p - s);
295 return obstack_copy0 (&temporary_obstack, ext, strlen (ext));
299 obstack_fgets (stream, ob)
304 while ((c = getc (stream)) != EOF && c != '\n')
305 obstack_1grow (ob, c);
306 if (obstack_object_size (ob) == 0)
308 obstack_1grow (ob, '\0');
309 return obstack_finish (ob);
316 return obstack_fgets (stream, &temporary_obstack);
323 return obstack_fgets (stream, &permanent_obstack);
326 /* Real tlink code. */
329 freadsym (stream, f, chosen)
337 char *name = tfgets (stream);
338 sym = symbol_hash_lookup (name, true);
341 if (sym->file == NULL)
345 sym->chosen = chosen;
349 if (sym->chosen && sym->file != f)
351 if (sym->chosen == 1)
352 file_push (sym->file);
357 chosen = sym->chosen;
361 sym->chosen = chosen;
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)
380 f->args = pfgets (stream);
383 f->dir = pfgets (stream);
386 f->main = pfgets (stream);
389 freadsym (stream, f, 2);
392 freadsym (stream, f, 1);
395 freadsym (stream, f, 0);
398 obstack_free (&temporary_obstack, temporary_firstobj);
402 f->args = getenv ("COLLECT_GCC_OPTIONS");
408 maybe_tweak (line, f)
412 symbol *sym = symbol_hash_lookup (line + 2, false);
414 if ((sym->file == f && sym->tweaking)
415 || (sym->file != f && line[0] == 'C'))
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)
445 maybe_tweak (line, f);
447 fprintf (output, "%s\n", line);
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));
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)
472 obstack_free (&temporary_obstack, temporary_firstobj);
478 read_repo_files (object_lst)
481 char **object = object_lst;
483 for (; *object; object++)
485 char *p = frob_extension (*object, ".rpo");
488 if (! file_exists (p))
491 f = file_hash_lookup (p);
496 if (file_stack != NULL && ! recompile_files ())
499 return (symbol_stack != NULL);
503 demangle_new_symbols ()
507 while ((sym = symbol_pop ()) != NULL)
510 char *p = cplus_demangle (sym->root.string, DMGL_PARAMS | DMGL_ANSI);
515 dem = demangled_hash_lookup (p, true);
516 dem->mangled = sym->root.string;
521 scan_linker_output (fname)
524 FILE *stream = fopen (fname, "r");
527 while ((line = tfgets (stream)) != NULL)
533 while (*p && ISSPACE (*p))
539 for (q = p; *q && ! ISSPACE (*q); ++q)
542 /* Try the first word on the line. */
545 if (*p == '_' && prepends_underscore)
550 sym = symbol_hash_lookup (p, false);
553 /* Try a mangled name in quotes. */
559 /* First try `GNU style'. */
560 p = index (oldq, '`');
562 p++, q = index (p, '\'');
563 /* Then try "double quotes". */
564 else if (p = index (oldq, '"'), p)
565 p++, q = index (p, '"');
570 dem = demangled_hash_lookup (p, false);
572 sym = symbol_hash_lookup (dem->mangled, false);
574 sym = symbol_hash_lookup (p, false);
578 if (sym && sym->tweaked)
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);
589 file_push (sym->file);
592 obstack_free (&temporary_obstack, temporary_firstobj);
596 return (file_stack != NULL);
600 do_tlink (ld_argv, object_lst)
601 char **ld_argv, **object_lst;
603 int exit = tlink_execute ("ld", ld_argv, ldout);
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)
618 demangle_new_symbols ();
619 if (! scan_linker_output (ldout))
621 if (! recompile_files ())
624 fprintf (stderr, "collect: relinking\n");
625 exit = tlink_execute ("ld", ld_argv, ldout);
633 error ("ld returned %d exit status", exit);