/* Scan linker error messages for missing template instantiations and provide
them.
- Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004
+ Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004, 2005
Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com).
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
#include "config.h"
#include "system.h"
static void file_push (file *);
static file * file_pop (void);
static void tlink_init (void);
-static int tlink_execute (const char *, char **, const char *);
+static int tlink_execute (const char *, char **, const char *, const char *);
static char * frob_extension (const char *, const char *);
static char * obstack_fgets (FILE *, struct obstack *);
static char * tfgets (FILE *);
if (*e == NULL)
{
struct symbol_hash_entry *v;
- *e = v = xcalloc (1, sizeof (*v));
+ *e = v = XCNEW (struct symbol_hash_entry);
v->key = xstrdup (string);
}
return *e;
if (*e == NULL)
{
struct file_hash_entry *v;
- *e = v = xcalloc (1, sizeof (*v));
+ *e = v = XCNEW (struct file_hash_entry);
v->key = xstrdup (string);
}
return *e;
if (*e == NULL)
{
struct demangled_hash_entry *v;
- *e = v = xcalloc (1, sizeof (*v));
+ *e = v = XCNEW (struct demangled_hash_entry);
v->key = xstrdup (string);
}
return *e;
}
static int
-tlink_execute (const char *prog, char **argv, const char *redir)
+tlink_execute (const char *prog, char **argv, const char *outname,
+ const char *errname)
{
- collect_execute (prog, argv, redir);
- return collect_wait (prog);
+ struct pex_obj *pex;
+
+ pex = collect_execute (prog, argv, outname, errname);
+ return collect_wait (prog, pex);
}
static char *
if (obstack_object_size (ob) == 0)
return NULL;
obstack_1grow (ob, '\0');
- return obstack_finish (ob);
+ return XOBFINISH (ob, char *);
}
static char *
}
fclose (stream);
fclose (output);
- rename (outname, f->key);
+ /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if
+ the new file name already exists. Therefore, we explicitly
+ remove the old file first. */
+ if (remove (f->key) == -1)
+ fatal_perror ("removing .rpo file");
+ if (rename (outname, f->key) == -1)
+ fatal_perror ("renaming .rpo file");
if (!f->args)
{
done:
obstack_ptr_grow (&temporary_obstack, f->main);
obstack_ptr_grow (&temporary_obstack, NULL);
- argv = obstack_finish (&temporary_obstack);
+ argv = XOBFINISH (&temporary_obstack, char **);
if (tlink_verbose)
fprintf (stderr, _("collect: recompiling %s\n"), f->main);
if (chdir (f->dir) != 0
- || tlink_execute (c_file_name, argv, NULL) != 0
+ || tlink_execute (c_file_name, argv, NULL, NULL) != 0
|| chdir (initial_cwd) != 0)
return 0;
{
FILE *stream = fopen (fname, "r");
char *line;
+ int skip_next_line = 0;
while ((line = tfgets (stream)) != NULL)
{
char *p = line, *q;
symbol *sym;
int end;
+ int ok = 0;
+
+ if (skip_next_line)
+ continue;
while (*p && ISSPACE ((unsigned char) *p))
++p;
demangled *dem = 0;
q = 0;
+ /* On darwin9, we look for "foo" referenced from:\n.*\n */
+ if (strcmp (oldq, "referenced from:") == 0)
+ {
+ /* We have to remember that we found a symbol to tweak. */
+ ok = 1;
+
+ /* We actually want to start from the first word on the line. */
+ oldq = p;
+
+ /* Since the format is multiline, we have to skip the next line. */
+ skip_next_line = 1;
+ }
+
/* First try `GNU style'. */
p = strchr (oldq, '`');
if (p)
/* We need to check for certain error keywords here, or we would
mistakenly use GNU ld's "In function `foo':" message. */
- if (q && (strstr (oldq, "ndefined")
+ if (q && (ok
+ || strstr (oldq, "ndefined")
|| strstr (oldq, "nresolved")
|| strstr (oldq, "nsatisfied")
|| strstr (oldq, "ultiple")))
void
do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
{
- int exit = tlink_execute ("ld", ld_argv, ldout);
+ int exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
tlink_init ();
while (exit && i++ < MAX_ITERATIONS)
{
if (tlink_verbose >= 3)
- dump_file (ldout);
+ {
+ dump_file (ldout, stdout);
+ dump_file (lderrout, stderr);
+ }
demangle_new_symbols ();
- if (! scan_linker_output (ldout))
+ if (! scan_linker_output (ldout)
+ && ! scan_linker_output (lderrout))
break;
if (! recompile_files ())
break;
if (tlink_verbose)
fprintf (stderr, _("collect: relinking\n"));
- exit = tlink_execute ("ld", ld_argv, ldout);
+ exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
}
}
- dump_file (ldout);
+ dump_file (ldout, stdout);
unlink (ldout);
+ dump_file (lderrout, stderr);
+ unlink (lderrout);
if (exit)
{
error ("ld returned %d exit status", exit);