+2019-09-06 Martin Liska <mliska@suse.cz>
+
+ PR c++/91125
+ * Makefile.in: Remove tlink.o.
+ * collect2.c (do_link): New function isolated
+ from do_tlink.
+ (main): Use.
+ * collect2.h (do_tlink): Remove declaration of do_tlink.
+ * doc/extend.texi: Remove documentation of -frepo.
+ * doc/invoke.texi: Likewise.
+ * doc/sourcebuild.texi: Remove cleanup-repo-files.
+ * tlink.c: Remove.
+
2019-09-05 Jakub Jelinek <jakub@redhat.com>
Jim Wilson <jimw@sifive.com>
gcc-nm.c: gcc-ar.c
cp $^ $@
-COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o \
+COLLECT2_OBJS = collect2.o collect2-aix.o vec.o ggc-none.o \
collect-utils.o file-find.o hash-table.o selftest.o
COLLECT2_LIBS = @COLLECT2_LIBS@
collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
+2019-09-06 Martin Liska <mliska@suse.cz>
+
+ PR c++/91125
+ * c-common.c: Remove definition of flag_use_repository.
+ * c-common.h: Likewise.
+ * c-opts.c (c_common_handle_option):
+ Do not handle OPT_frepo option.
+ * c.opt: Mark the option with Deprecated.
+
2019-09-04 Marek Polacek <polacek@redhat.com>
* c.opt (fdeduce-init-list): Ignored.
int warn_abi_version = -1;
-/* Nonzero means generate separate instantiation control files and
- juggle them at link time. */
-
-int flag_use_repository;
-
/* The C++ dialect being used. Default set in c_common_post_options. */
enum cxx_dialect cxx_dialect = cxx_unset;
!= (warn_abi_version == 0 \
|| warn_abi_version >= (N)))
-/* Nonzero means generate separate instantiation control files and
- juggle them at link time. */
-
-extern int flag_use_repository;
-
/* The supported C++ dialects. */
enum cxx_dialect {
cpp_opts->track_macro_expansion = 2;
break;
- case OPT_frepo:
- flag_use_repository = value;
- if (value)
- flag_implicit_templates = 0;
- break;
-
case OPT_ftabstop_:
/* It is documented that we silently ignore silly values. */
if (value >= 1 && value <= 100)
Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime.
frepo
-C++ ObjC++
-Enable automatic template instantiation.
+C++ ObjC++ Deprecated
+Deprecated in GCC 10. This switch has no effect.
frtti
C++ ObjC++ Optimization Var(flag_rtti) Init(1)
else
post_ld_pass (false); /* No LTO objects were found, no temp file. */
}
+/* Entry point for linker invoation. Called from main in collect2.c.
+ LD_ARGV is an array of arguments for the linker. */
+
+static void
+do_link (char **ld_argv)
+{
+ struct pex_obj *pex;
+ const char *prog = "ld";
+ pex = collect_execute (prog, ld_argv, NULL, NULL,
+ PEX_LAST | PEX_SEARCH,
+ HAVE_GNU_LD && at_file_supplied);
+ int ret = collect_wait (prog, pex);
+ if (ret)
+ {
+ error ("ld returned %d exit status", ret);
+ exit (ret);
+ }
+ else
+ {
+ /* We have just successfully produced an output file, so assume that we
+ may unlink it if need be for now on. */
+ may_unlink_output_file = true;
+ }
+}
\f
/* Main program. */
functions from precise cross reference insertions by the compiler. */
if (early_exit || ld1_filter != SCAN_NOTHING)
- do_tlink (ld1_argv, object_lst);
+ do_link (ld1_argv);
if (early_exit)
{
#endif
)
{
- /* Do tlink without additional code generation now if we didn't
+ /* Do link without additional code generation now if we didn't
do it earlier for scanning purposes. */
if (ld1_filter == SCAN_NOTHING)
- do_tlink (ld1_argv, object_lst);
+ do_link (ld1_argv);
if (lto_mode)
maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
fork_execute ("gcc", c_argv, at_file_supplied);
#ifdef COLLECT_EXPORT_LIST
- /* On AIX we must call tlink because of possible templates resolution. */
- do_tlink (ld2_argv, object_lst);
+ /* On AIX we must call link because of possible templates resolution. */
+ do_link (ld2_argv);
if (lto_mode)
maybe_run_lto_and_relink (ld2_argv, object_lst, object, false);
#else
- /* Otherwise, simply call ld because tlink is already done. */
+ /* Otherwise, simply call ld because link is already done. */
if (lto_mode)
maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
else
-/* Header file for collect/tlink routines.
+/* Header file for collect routines.
Copyright (C) 1998-2019 Free Software Foundation, Inc.
This file is part of GCC.
#ifndef GCC_COLLECT2_H
#define GCC_COLLECT2_H
-extern void do_tlink (char **, char **);
-
extern struct pex_obj *collect_execute (const char *, char **, const char *,
const char *, int flags);
+2019-09-06 Martin Liska <mliska@suse.cz>
+
+ PR c++/91125
+ * Make-lang.in: Remove repo.o.
+ * config-lang.in: Likewise.
+ * cp-tree.h (init_repo): Remove declarations
+ of repo-related functions.
+ (repo_emit_p): Likewise.
+ (repo_export_class_p): Likewise.
+ (finish_repo): Likewise.
+ * decl2.c (import_export_class): Always
+ set -1 value/
+ (mark_needed): Remove -frepo from comment.
+ (import_export_decl): Similarly here.
+ (c_parse_final_cleanups): Remove call of finish_repo.
+ * lex.c (cxx_init): Remove call to init_repo.
+ * optimize.c (can_alias_cdtor): Remove dead condition.
+ * pt.c (push_template_decl_real): Update comment.
+ (instantiate_decl): Remove dead code used for -frepo.
+ * repo.c: Remove.
+
2019-09-05 Marek Polacek <polacek@redhat.com>
PR c++/91644 - ICE with constinit in function template.
cp/mangle.o cp/method.o \
cp/name-lookup.o cp/optimize.o \
cp/parser.o cp/pt.o cp/ptree.o \
- cp/repo.o cp/rtti.o \
+ cp/rtti.o \
cp/search.o cp/semantics.o \
cp/tree.o cp/typeck.o cp/typeck2.o \
cp/vtable-class-hierarchy.o $(CXX_C_OBJS)
\$(srcdir)/cp/mangle.c \$(srcdir)/cp/method.c \
\$(srcdir)/cp/name-lookup.c \
\$(srcdir)/cp/parser.c \$(srcdir)/cp/pt.c \
-\$(srcdir)/cp/repo.c \$(srcdir)/cp/rtti.c \
+\$(srcdir)/cp/rtti.c \
\$(srcdir)/cp/semantics.c \
\$(srcdir)/cp/tree.c \$(srcdir)/cp/typeck2.c \
\$(srcdir)/cp/vtable-class-hierarchy.c \
extern bool template_guide_p (const_tree);
extern void store_explicit_specifier (tree, tree);
-/* in repo.c */
-extern void init_repo (void);
-extern int repo_emit_p (tree);
-extern bool repo_export_class_p (const_tree);
-extern void finish_repo (void);
-
/* in rtti.c */
/* A vector of all tinfo decls that haven't been emitted yet. */
extern GTY(()) vec<tree, va_gc> *unemitted_tinfo_decls;
repository. If the virtual table is assigned to this
translation unit, then export the class; otherwise, import
it. */
- import_export = repo_export_class_p (ctype) ? 1 : -1;
+ import_export = -1;
else if (TYPE_POLYMORPHIC_P (ctype))
{
/* The ABI specifies that the virtual table and associated
struct cgraph_node *node = cgraph_node::get_create (decl);
node->forced_by_abi = true;
- /* #pragma interface and -frepo code can call mark_needed for
+ /* #pragma interface can call mark_needed for
maybe-in-charge 'tors; mark the clones as well. */
tree clone;
FOR_EACH_CLONE (clone, decl)
void
import_export_decl (tree decl)
{
- int emit_p;
bool comdat_p;
bool import_p;
tree class_type = NULL_TREE;
/* We cannot determine what linkage to give to an entity with vague
linkage until the end of the file. For example, a virtual table
for a class will be defined if and only if the key method is
- defined in this translation unit. As a further example, consider
- that when compiling a translation unit that uses PCH file with
- "-frepo" it would be incorrect to make decisions about what
- entities to emit when building the PCH; those decisions must be
- delayed until the repository information has been processed. */
+ defined in this translation unit. */
gcc_assert (at_eof);
/* Object file linkage for explicit instantiations is handled in
mark_decl_instantiated. For static variables in functions with
unit. */
import_p = false;
- /* See if the repository tells us whether or not to emit DECL in
- this translation unit. */
- emit_p = repo_emit_p (decl);
- if (emit_p == 0)
- import_p = true;
- else if (emit_p == 1)
- {
- /* The repository indicates that this entity should be defined
- here. Make sure the back end honors that request. */
- mark_needed (decl);
- /* Output the definition as an ordinary strong definition. */
- DECL_EXTERNAL (decl) = 0;
- DECL_INTERFACE_KNOWN (decl) = 1;
- return;
- }
-
- if (import_p)
- /* We have already decided what to do with this DECL; there is no
- need to check anything further. */
- ;
- else if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
+ if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
{
class_type = DECL_CONTEXT (decl);
import_export_class (class_type);
{
/* DECL is an implicit instantiation of a function or static
data member. */
- if ((flag_implicit_templates
- && !flag_use_repository)
+ if (flag_implicit_templates
|| (flag_implicit_inline_templates
&& TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)))
perform_deferred_noexcept_checks ();
- finish_repo ();
fini_constexpr ();
/* The entire file is now complete. If requested, dump everything
init_cp_pragma ();
- init_repo ();
-
input_location = saved_loc;
return true;
}
/* We can't use an alias if there are virtual bases. */
if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
return false;
- /* ??? Why not use aliases with -frepo? */
- if (flag_use_repository)
- return false;
gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
/* Don't use aliases for weak/linkonce definitions unless we can put both
symbols in the same COMDAT group. */
&& TREE_PUBLIC (decl)
&& VAR_OR_FUNCTION_DECL_P (decl))
/* Set DECL_COMDAT on template instantiations; if we force
- them to be emitted by explicit instantiation or -frepo,
+ them to be emitted by explicit instantiation,
mark_needed will tell cgraph to do the right thing. */
DECL_COMDAT (decl) = true;
add_pending_template (d);
goto out;
}
- /* Tell the repository that D is available in this translation unit
- -- and see if it is supposed to be instantiated here. */
- if (TREE_PUBLIC (d) && !DECL_REALLY_EXTERN (d) && !repo_emit_p (d))
- {
- /* In a PCH file, despite the fact that the repository hasn't
- requested instantiation in the PCH it is still possible that
- an instantiation will be required in a file that includes the
- PCH. */
- if (pch_file)
- add_pending_template (d);
- /* Instantiate inline functions so that the inliner can do its
- job, even though we'll not be emitting a copy of this
- function. */
- if (!(TREE_CODE (d) == FUNCTION_DECL && possibly_inlined_p (d)))
- goto out;
- }
bool push_to_top, nested;
tree fn_context;
+++ /dev/null
-/* Code to maintain a C++ template repository.
- Copyright (C) 1995-2019 Free Software Foundation, Inc.
- Contributed by Jason Merrill (jason@cygnus.com)
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-/* My strategy here is as follows:
-
- Everything should be emitted in a translation unit where it is used.
- The results of the automatic process should be easily reproducible with
- explicit code. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "cp-tree.h"
-#include "stringpool.h"
-#include "toplev.h"
-
-static const char *extract_string (const char **);
-static const char *get_base_filename (const char *);
-static FILE *open_repo_file (const char *);
-static char *afgets (FILE *);
-static FILE *reopen_repo_file_for_write (void);
-
-static GTY(()) vec<tree, va_gc> *pending_repo;
-static char *repo_name;
-
-static const char *old_args, *old_dir, *old_main;
-
-static struct obstack temporary_obstack;
-static bool temporary_obstack_initialized_p;
-
-/* Parse a reasonable subset of shell quoting syntax. */
-
-static const char *
-extract_string (const char **pp)
-{
- const char *p = *pp;
- int backquote = 0;
- int inside = 0;
-
- for (;;)
- {
- char c = *p;
- if (c == '\0')
- break;
- ++p;
- if (backquote)
- {
- obstack_1grow (&temporary_obstack, c);
- backquote = 0;
- }
- else if (! inside && c == ' ')
- break;
- else if (! inside && c == '\\')
- backquote = 1;
- else if (c == '\'')
- inside = !inside;
- else
- obstack_1grow (&temporary_obstack, c);
- }
-
- obstack_1grow (&temporary_obstack, '\0');
- *pp = p;
- return (char *) obstack_finish (&temporary_obstack);
-}
-
-static const char *
-get_base_filename (const char *filename)
-{
- const char *p = getenv ("COLLECT_GCC_OPTIONS");
- const char *output = NULL;
- int compiling = 0;
-
- while (p && *p)
- {
- const char *q = extract_string (&p);
-
- if (strcmp (q, "-o") == 0)
- {
- if (flag_compare_debug)
- /* Just in case aux_base_name was based on a name with two
- or more '.'s, add an arbitrary extension that will be
- stripped by the caller. */
- output = concat (aux_base_name, ".o", NULL);
- else
- output = extract_string (&p);
- }
- else if (strcmp (q, "-c") == 0)
- compiling = 1;
- }
-
- if (compiling && output)
- return output;
-
- if (p && ! compiling)
- {
- warning (0, "%<-frepo%> must be used with %<-c%>");
- flag_use_repository = 0;
- return NULL;
- }
-
- return lbasename (filename);
-}
-
-static FILE *
-open_repo_file (const char *filename)
-{
- const char *p;
- const char *s = get_base_filename (filename);
-
- if (s == NULL)
- return NULL;
-
- p = lbasename (s);
- p = strrchr (p, '.');
- if (! p)
- p = s + strlen (s);
-
- repo_name = XNEWVEC (char, p - s + 5);
- memcpy (repo_name, s, p - s);
- memcpy (repo_name + (p - s), ".rpo", 5);
-
- return fopen (repo_name, "r");
-}
-
-static char *
-afgets (FILE *stream)
-{
- int c;
- while ((c = getc (stream)) != EOF && c != '\n')
- obstack_1grow (&temporary_obstack, c);
- if (obstack_object_size (&temporary_obstack) == 0)
- return NULL;
- obstack_1grow (&temporary_obstack, '\0');
- return (char *) obstack_finish (&temporary_obstack);
-}
-
-void
-init_repo (void)
-{
- char *buf;
- const char *p;
- FILE *repo_file;
-
- if (! flag_use_repository)
- return;
-
- /* When a PCH file is loaded, the entire identifier table is
- replaced, with the result that IDENTIFIER_REPO_CHOSEN is cleared.
- So, we have to reread the repository file. */
- lang_post_pch_load = init_repo;
-
- if (!temporary_obstack_initialized_p)
- gcc_obstack_init (&temporary_obstack);
-
- repo_file = open_repo_file (main_input_filename);
-
- if (repo_file == 0)
- return;
-
- while ((buf = afgets (repo_file)))
- {
- switch (buf[0])
- {
- case 'A':
- old_args = ggc_strdup (buf + 2);
- break;
- case 'D':
- old_dir = ggc_strdup (buf + 2);
- break;
- case 'M':
- old_main = ggc_strdup (buf + 2);
- break;
- case 'O':
- /* A symbol that we were able to define the last time this
- file was compiled. */
- break;
- case 'C':
- /* A symbol that the prelinker has requested that we
- define. */
- {
- tree id = get_identifier (buf + 2);
- IDENTIFIER_REPO_CHOSEN (id) = 1;
- }
- break;
- default:
- error ("mysterious repository information in %s", repo_name);
- }
- obstack_free (&temporary_obstack, buf);
- }
- fclose (repo_file);
-
- if (old_args && !get_random_seed (true)
- && (p = strstr (old_args, "'-frandom-seed=")))
- set_random_seed (extract_string (&p) + strlen ("-frandom-seed="));
-}
-
-static FILE *
-reopen_repo_file_for_write (void)
-{
- FILE *repo_file = fopen (repo_name, "w");
-
- if (repo_file == 0)
- {
- error ("cannot create repository information file %qs", repo_name);
- flag_use_repository = 0;
- }
-
- return repo_file;
-}
-
-/* Emit any pending repos. */
-
-void
-finish_repo (void)
-{
- tree val;
- char *dir, *args;
- FILE *repo_file;
- unsigned ix;
-
- if (!flag_use_repository || flag_compare_debug)
- return;
-
- if (seen_error ())
- return;
-
- repo_file = reopen_repo_file_for_write ();
- if (repo_file == 0)
- goto out;
-
- fprintf (repo_file, "M %s\n", main_input_filename);
- dir = getpwd ();
- fprintf (repo_file, "D %s\n", dir);
- args = getenv ("COLLECT_GCC_OPTIONS");
- if (args)
- {
- fprintf (repo_file, "A %s", args);
- /* If -frandom-seed is not among the ARGS, then add the value
- that we chose. That will ensure that the names of types from
- anonymous namespaces will get the same mangling when this
- file is recompiled. */
- if (!strstr (args, "'-frandom-seed="))
- fprintf (repo_file, " '-frandom-seed=" HOST_WIDE_INT_PRINT_HEX_PURE "'",
- get_random_seed (false));
- fprintf (repo_file, "\n");
- }
-
- FOR_EACH_VEC_SAFE_ELT_REVERSE (pending_repo, ix, val)
- {
- tree name = DECL_ASSEMBLER_NAME (val);
- char type = IDENTIFIER_REPO_CHOSEN (name) ? 'C' : 'O';
- fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (name));
- }
-
- out:
- if (repo_file)
- fclose (repo_file);
-}
-
-/* DECL is a FUNCTION_DECL or VAR_DECL with vague linkage whose
- definition is available in this translation unit. Returns 0 if
- this definition should not be emitted in this translation unit
- because it will be emitted elsewhere. Returns 1 if the repository
- file indicates that that DECL should be emitted in this translation
- unit, or 2 if the repository file is not in use. */
-
-int
-repo_emit_p (tree decl)
-{
- int ret = 0;
- gcc_assert (TREE_PUBLIC (decl));
- gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
- gcc_assert (!DECL_REALLY_EXTERN (decl)
- /* A clone might not have its linkage flags updated yet
- because we call import_export_decl before
- maybe_clone_body. */
- || DECL_ABSTRACT_ORIGIN (decl));
-
- /* When not using the repository, emit everything. */
- if (!flag_use_repository)
- return 2;
-
- /* Only template instantiations are managed by the repository. This
- is an artificial restriction; the code in the prelinker and here
- will work fine if all entities with vague linkage are managed by
- the repository. */
- if (VAR_P (decl))
- {
- tree type = NULL_TREE;
- if (DECL_VTABLE_OR_VTT_P (decl))
- type = DECL_CONTEXT (decl);
- else if (DECL_TINFO_P (decl))
- type = TREE_TYPE (DECL_NAME (decl));
- if (!DECL_TEMPLATE_INSTANTIATION (decl)
- && (!TYPE_LANG_SPECIFIC (type)
- || !CLASSTYPE_TEMPLATE_INSTANTIATION (type)))
- return 2;
- /* Const static data members initialized by constant expressions must
- be processed where needed so that their definitions are
- available. Still record them into *.rpo files, so if they
- weren't actually emitted and collect2 requests them, they can
- be provided. */
- if (decl_maybe_constant_var_p (decl)
- && DECL_CLASS_SCOPE_P (decl))
- ret = 2;
- }
- else if (!DECL_TEMPLATE_INSTANTIATION (decl))
- return 2;
-
- if (DECL_EXPLICIT_INSTANTIATION (decl))
- return 2;
-
- /* For constructors and destructors, the repository contains
- information about the clones -- not the original function --
- because only the clones are emitted in the object file. */
- if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
- {
- int emit_p = 0;
- tree clone;
- /* There is no early exit from this loop because we want to
- ensure that all of the clones are marked as available in this
- object file. */
- FOR_EACH_CLONE (clone, decl)
- /* The only possible results from the recursive call to
- repo_emit_p are 0 or 1. */
- if (repo_emit_p (clone))
- emit_p = 1;
- return emit_p;
- }
-
- /* Keep track of all available entities. */
- if (!DECL_REPO_AVAILABLE_P (decl))
- {
- DECL_REPO_AVAILABLE_P (decl) = 1;
- vec_safe_push (pending_repo, decl);
- }
-
- return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret;
-}
-
-/* Returns true iff the prelinker has explicitly marked CLASS_TYPE for
- export from this translation unit. */
-
-bool
-repo_export_class_p (const_tree class_type)
-{
- if (!flag_use_repository)
- return false;
- if (!CLASSTYPE_VTABLES (class_type))
- return false;
- /* If the virtual table has been assigned to this translation unit,
- export the class. */
- return (IDENTIFIER_REPO_CHOSEN
- (DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (class_type))));
-}
-
-#include "gt-cp-repo.h"
alternative and programs using this approach will work with most modern
compilers.
-@item
-@opindex frepo
-Compile your template-using code with @option{-frepo}. The compiler
-generates files with the extension @samp{.rpo} listing all of the
-template instantiations used in the corresponding object files that
-could be instantiated there; the link wrapper, @samp{collect2},
-then updates the @samp{.rpo} files to tell the compiler where to place
-those instantiations and rebuild any affected object files. The
-link-time overhead is negligible after the first pass, as the compiler
-continues to place the instantiations in the same files.
-
-This can be a suitable option for application code written for the Borland
-model, as it usually just works. Code written for the Cfront model
-needs to be modified so that the template definitions are available at
-one or more points of instantiation; usually this is as simple as adding
-@code{#include <tmethods.cc>} to the end of each template header.
-
-For library code, if you want the library to provide all of the template
-instantiations it needs, just try to link all of its object files
-together; the link will fail, but cause the instantiations to be
-generated as a side effect. Be warned, however, that this may cause
-conflicts if multiple libraries try to provide the same instantiations.
-For greater control, use explicit instantiation as described in the next
-option.
-
@item
@opindex fno-implicit-templates
Compile your code with @option{-fno-implicit-templates} to disable the
-fno-nonansi-builtins -fnothrow-opt -fno-operator-names @gol
-fno-optional-diags -fpermissive @gol
-fno-pretty-templates @gol
--frepo -fno-rtti -fsized-deallocation @gol
+-fno-rtti -fsized-deallocation @gol
-ftemplate-backtrace-limit=@var{n} @gol
-ftemplate-depth=@var{n} @gol
-fno-threadsafe-statics -fuse-cxa-atexit @gol
behaviors make it harder to understand the error message rather than
easier, you can use @option{-fno-pretty-templates} to disable them.
-@item -frepo
-@opindex frepo
-Enable automatic template instantiation at link time. This option also
-implies @option{-fno-implicit-templates}. @xref{Template
-Instantiation}, for more information.
-
@item -fno-rtti
@opindex fno-rtti
@opindex frtti
@item cleanup-profile-file
Removes profiling files generated for this test.
-@item cleanup-repo-files
-Removes files generated for this test for @option{-frepo}.
-
@end table
@node Ada Tests
+2019-09-06 Martin Liska <mliska@suse.cz>
+
+ PR c++/91125
+ * g++.dg/parse/repo1.C: Remove.
+ * g++.dg/rtti/repo1.C: Remove.
+ * g++.dg/template/repo1.C: Remove.
+ * g++.dg/template/repo10.C: Remove.
+ * g++.dg/template/repo11.C: Remove.
+ * g++.dg/template/repo2.C: Remove.
+ * g++.dg/template/repo3.C: Remove.
+ * g++.dg/template/repo4.C: Remove.
+ * g++.dg/template/repo5.C: Remove.
+ * g++.dg/template/repo6.C: Remove.
+ * g++.dg/template/repo7.C: Remove.
+ * g++.dg/template/repo8.C: Remove.
+ * g++.dg/template/repo9.C: Remove.
+ * g++.old-deja/g++.pt/instantiate4.C: Remove.
+ * g++.old-deja/g++.pt/instantiate6.C: Remove.
+ * g++.old-deja/g++.pt/repo1.C: Remove.
+ * g++.old-deja/g++.pt/repo2.C: Remove.
+ * g++.old-deja/g++.pt/repo3.C: Remove.
+ * g++.old-deja/g++.pt/repo4.C: Remove.
+ * lib/g++.exp: Remove removal of repo files.
+ * lib/gcc-dg.exp: Likewise.
+ * lib/obj-c++.exp: Likewise.
+
2019-09-05 Jakub Jelinek <jakub@redhat.com>
Jim Wilson <jimw@sifive.com>
+++ /dev/null
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-
-extern "C" inline void f() {}
-
-int main () {
- f();
-}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// PR c++/22204
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-#include <typeinfo>
-template<int>
-struct function1
-{
- function1()
- {
- typeid(int[100]);
- }
-};
-function1<1> b;
-
-int main () {}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-struct A {
- A();
-};
-
-A::A() {}
-
-template <typename T>
-struct B : public A {
- B() {} // { dg-bogus "" }
-};
-
-B<int> b;
-
-int main () {}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// PR c++/51910
-// { dg-options -frepo }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-// { dg-final cleanup-repo-files }
-
-template<typename T>
-struct Foo
-{
- virtual ~Foo() { }
-};
-
-int main( int, char*[] )
-{
- Foo<int> test;
-}
+++ /dev/null
-// PR c++/64521
-// { dg-options "-frepo -std=c++11" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-// { dg-final cleanup-repo-files }
-
-template <typename H> struct J { J(H) {} };
-template <unsigned long, typename...> struct K;
-template <unsigned long I> struct K<I> {};
-template <unsigned long I, typename H, typename... T>
-struct K<I, H, T...> : K<I + 1, T...>, J<H> {
- K(const H &p1, const T &... p2) : K<I + 1, T...>(p2...), J<H>(p1) {}
-};
-template <typename... E> struct C : K<0, E...> {
- C(const E &... p1) : K<0, E...>(p1...) {}
-};
-template <typename> struct A {
- A() = default;
-};
-struct M;
-template <typename> struct L {
- struct B {
- template <typename> static M *__test(...);
- typedef A<int> _Del;
- typedef decltype(__test<_Del>()) type;
- };
- C<typename B::type, A<M>> _M_t;
- L(typename B::type) : _M_t(0, A<M>()) {}
-};
-struct M {};
-int main() { L<int>(new M); }
+++ /dev/null
-// PR c++/17163
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-template <int __inst>
-struct __Atomicity_lock
-{
- static unsigned char _S_atomicity_lock;
-};
-template <int __inst>
-unsigned char __Atomicity_lock<__inst>::_S_atomicity_lock = 0;
-template unsigned char __Atomicity_lock<0>::_S_atomicity_lock;
-
-int main () {
-}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// { dg-options "-frepo -DF='a'" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-template <typename A, typename B> void f () {}
-template <typename A, typename B> void g () { f<int,int>(); }
-int main () { g<int,int>(); }
-
-char c = F;
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// PR c++/17775
-// { dg-options "-frepo" }
-// { dg-final { cleanup-repo-files } }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-namespace {
- struct Foo {};
-}
-
-template <typename Tp>
-void foo(Tp) {}
-
-int
-main()
-{
- foo(Foo());
-}
+++ /dev/null
-// PR c++/25625
-// { dg-options "-frepo" }
-// { dg-final { cleanup-repo-files } }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-template< typename T, T N > struct integral_c {
- static const T value = N;
- typedef integral_c< T, value + 1 > next;
-};
-template< typename T, T N > T const integral_c< T, N >::value;
-integral_c<int,0> a;
-
-int main () {}
+++ /dev/null
-// PR c++/34178
-// { dg-options "-frepo" }
-// { dg-final { cleanup-repo-files } }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-template<typename T>
-class A
-{
-private:
- static const int x;
- static int y;
-
-public:
- int getX () { return x + y; }
-};
-
-template<typename T> const int A<T>::x = 0;
-template<typename T> int A<T>::y = 0;
-
-int
-main ()
-{
- A<int> a;
- return a.getX();
-}
+++ /dev/null
-// PR c++/34340
-// { dg-options "-frepo" }
-// { dg-final { cleanup-repo-files } }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-struct A
-{
- int a;
-};
-
-template <typename T> struct D
-{
- static const A b;
-};
-
-template<typename T> const A D<T>::b = { 2 };
-template class D<A>;
-
-const A *x = &D<A>::b;
-
-int
-main ()
-{
-}
+++ /dev/null
-// PR c++/34340
-// { dg-options "-frepo" }
-// { dg-final { cleanup-repo-files } }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-struct A
-{
- int a;
-};
-
-template <typename T> struct D
-{
- static const A b;
-};
-
-template<typename T> const A D<T>::b = { 2 };
-
-const A *x = &D<A>::b;
-
-int
-main ()
-{
-}
+++ /dev/null
-// PR c++/36364
-// { dg-options "-frepo" }
-// { dg-final { cleanup-repo-files } }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-template <typename C> struct A
-{
- static void assign (C &c1, const C &c2) { c1 = c2; }
-};
-
-template <typename C, typename T> struct B
-{
- struct D
- {
- static const C terminal;
- static unsigned long stor[];
- static D &empty_rep ()
- {
- void *p = reinterpret_cast <void *>(&stor);
- return *reinterpret_cast <D *>(p);
- }
- void test (unsigned long n)
- {
- T::assign (this->refdata ()[n], terminal);
- }
- C *refdata () throw ()
- {
- return reinterpret_cast <C *>(this + 1);
- }
- };
- C *dataplus;
- C *data () const { return dataplus; }
- D *rep () const { return &((reinterpret_cast < D * >(data ()))[-1]); }
- static D & empty_rep () { return D::empty_rep (); }
- B () : dataplus (empty_rep ().refdata ()) { }
- ~B () { }
- void push_back (C c) { rep ()->test (10); }
-};
-
-template <typename C, typename T> const C B <C, T>::D::terminal = C ();
-template <typename C, typename T> unsigned long B <C, T>::D::stor[64];
-
-int
-main ()
-{
- B <char, A <char> > s;
- s.push_back ('a');
-}
+++ /dev/null
-// { dg-do link }
-// { dg-options "-frepo -Werror" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-
-// Submitted by Melissa O'Neill <oneill@cs.sfu.ca>
-// the vtable of Foo<int> wouldn't be generated
-
-template <typename A>
-struct Foo {
- virtual void foo() {}
-};
-
-template <typename A>
-struct Bar {
- void bar();
-};
-
-template <typename A>
-void Bar<A>::bar() {
- Foo<A> oof;
-}
-
-int main () {
- Bar<int> rab;
-
- rab.bar();
-}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// { dg-do link }
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-// Simplified from testcase by Erez Louidor Lior <s3824888@techst02.technion.ac.il>
-
-template <class T>
-class foo{
-public:
- void g();
- void h();
-};
-
-template <class T>
-void foo<T>::g() {
- h();
-}
-
-template <class T>
-void foo<T>::h() {
-}
-
-int main() {
- foo<int> f;
- f.g();
-}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// { dg-do link }
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-// Bug: g++ complains about duplicate explicit instantiations with -frepo.
-// From Jason Merrill <jason@cygnus.com>
-
-// Build then link:
-
-template <class T> struct A {
- virtual ~A () { }
-};
-
-template <class T> void g (T t) { }
-
-template class A<int>;
-
-int main ()
-{
- g (42);
-}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// { dg-do link }
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-// Test that collect2 isn't confused by GNU ld's "In function `foo':" message.
-// Contributed by Jason Merrill <jason@cygnus.com>
-
-// Build then link:
-
-template <class T>
-T f (T t)
-{
- return t;
-}
-
-template <class T>
-T g (T t)
-{
- return f (t);
-}
-
-int main ()
-{
- int i = g (42);
-}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// { dg-do link }
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-// Test that we properly generate the vtable and such for C.
-// Contributed by scott snyder <snyder@fnal.gov>
-
-// Build then link:
-
-struct A
-{
- virtual ~A () {}
-};
-
-template <typename T>
-struct B : virtual public A
-{
- virtual void foo () {}
-};
-
-template <typename T>
-struct C : virtual public A
-{
-};
-
-template <typename T>
-struct D : public B<T>, public C<T>
-{
-};
-
-int
-main ()
-{
- D<int> x;
- return 0;
-}
-
-// { dg-final { cleanup-repo-files } }
+++ /dev/null
-// { dg-do link }
-// { dg-options "-frepo" }
-// { dg-require-host-local "" }
-// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
-
-template <class T>
-struct S {
- ~S ();
-};
-
-template <class T>
-S<T>::~S () {}
-
-int main ()
-{
- S<int> s;
-}
-
-// { dg-final { cleanup-repo-files } }
set options [concat "$ALWAYS_CXXFLAGS" $options]
- if { [regexp "(^| )-frepo( |$)" $options] && \
- [regexp "\.o(|bj)$" $dest] } then {
- regsub "\.o(|bj)$" $dest ".rpo" rponame
- exec rm -f $rponame
- }
-
# bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is
# appended here to multilib_flags as it can be overridden by the latter
# if it was added earlier. After the target_compile, multilib_flags is
set options [list]
- # Tests should be able to use "dg-do repo". However, the dg test
- # driver checks the argument to dg-do against a list of acceptable
- # options, and "repo" is not among them. Therefore, we resort to
- # this ugly approach.
- if [string match "*-frepo*" $extra_tool_flags] then {
- set do_what "repo"
- }
-
switch $do_what {
"preprocess" {
set compile_type "preprocess"
}
}
-# Remove compiler-generated files from -repo for the current test.
-proc cleanup-repo-files { } {
- global additional_sources_used
- set testcase [testname-for-summary]
- # The name might include a list of options; extract the file name.
- set testcase [lindex $testcase 0]
- remove-build-file "[file rootname [file tail $testcase]].o"
- remove-build-file "[file rootname [file tail $testcase]].rpo"
-
- # Clean up files for additional source files.
- if [info exists additional_sources_used] {
- foreach srcfile $additional_sources_used {
- remove-build-file "[file rootname [file tail $srcfile]].o"
- remove-build-file "[file rootname [file tail $srcfile]].rpo"
- }
- }
-}
-
# Remove a final insns dump file for the current test.
proc cleanup-final-insns-dump { } {
set testcase [testname-for-summary]
set options [concat "$ALWAYS_OBJCXXFLAGS" $options];
- if { [regexp "(^| )-frepo( |$)" $options] && \
- [regexp "\.o(|bj)$" $dest] } then {
- regsub "\.o(|bj)$" $dest ".rpo" rponame
- exec rm -f $rponame
- }
-
set options [dg-additional-files-options $options $source]
set result [target_compile $source $dest $type $options]
+++ /dev/null
-/* Scan linker error messages for missing template instantiations and provide
- them.
-
- Copyright (C) 1995-2019 Free Software Foundation, Inc.
- Contributed by Jason Merrill (jason@cygnus.com).
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "intl.h"
-#include "obstack.h"
-#include "demangle.h"
-#include "collect2.h"
-#include "collect-utils.h"
-#include "filenames.h"
-#include "diagnostic-core.h"
-
-/* TARGET_64BIT may be defined to use driver specific functionality. */
-#undef TARGET_64BIT
-#define TARGET_64BIT TARGET_64BIT_DEFAULT
-
-#define MAX_ITERATIONS 17
-
-/* Defined in the automatically-generated underscore.c. */
-extern int prepends_underscore;
-
-static int tlink_verbose;
-
-static char *initial_cwd;
-\f
-/* Hash table boilerplate for working with htab_t. We have hash tables
- for symbol names, file names, and demangled symbols. */
-
-typedef struct symbol_hash_entry
-{
- const char *key;
- struct file_hash_entry *file;
- int chosen;
- int tweaking;
- int tweaked;
-} symbol;
-
-typedef struct file_hash_entry
-{
- const char *key;
- const char *args;
- const char *dir;
- const char *main;
- int tweaking;
-} file;
-
-typedef const char *str;
-
-typedef struct demangled_hash_entry
-{
- const char *key;
- vec<str> mangled;
-} demangled;
-
-/* Hash and comparison functions for these hash tables. */
-
-static int hash_string_eq (const void *, const void *);
-static hashval_t hash_string_hash (const void *);
-
-static int
-hash_string_eq (const void *s1_p, const void *s2_p)
-{
- const char *const *s1 = (const char *const *) s1_p;
- const char *s2 = (const char *) s2_p;
- return strcmp (*s1, s2) == 0;
-}
-
-static hashval_t
-hash_string_hash (const void *s_p)
-{
- const char *const *s = (const char *const *) s_p;
- return (*htab_hash_string) (*s);
-}
-
-static htab_t symbol_table;
-
-static struct symbol_hash_entry * symbol_hash_lookup (const char *, int);
-static struct file_hash_entry * file_hash_lookup (const char *);
-static struct demangled_hash_entry *demangled_hash_lookup (const char *, int);
-static void symbol_push (symbol *);
-static symbol * symbol_pop (void);
-static void file_push (file *);
-static file * file_pop (void);
-static char * frob_extension (const char *, const char *);
-static char * obstack_fgets (FILE *, struct obstack *);
-static char * tfgets (FILE *);
-static char * pfgets (FILE *);
-static void freadsym (FILE *, file *, int);
-static void read_repo_file (file *);
-static void maybe_tweak (char *, file *);
-static int recompile_files (void);
-static int read_repo_files (char **);
-static void demangle_new_symbols (void);
-static int scan_linker_output (const char *);
-
-/* Look up an entry in the symbol hash table. */
-
-static struct symbol_hash_entry *
-symbol_hash_lookup (const char *string, int create)
-{
- void **e;
- e = htab_find_slot_with_hash (symbol_table, string,
- (*htab_hash_string) (string),
- create ? INSERT : NO_INSERT);
- if (e == NULL)
- return NULL;
- if (*e == NULL)
- {
- struct symbol_hash_entry *v;
- *e = v = XCNEW (struct symbol_hash_entry);
- v->key = xstrdup (string);
- }
- return (struct symbol_hash_entry *) *e;
-}
-
-static htab_t file_table;
-
-/* Look up an entry in the file hash table. */
-
-static struct file_hash_entry *
-file_hash_lookup (const char *string)
-{
- void **e;
- e = htab_find_slot_with_hash (file_table, string,
- (*htab_hash_string) (string),
- INSERT);
- if (*e == NULL)
- {
- struct file_hash_entry *v;
- *e = v = XCNEW (struct file_hash_entry);
- v->key = xstrdup (string);
- }
- return (struct file_hash_entry *) *e;
-}
-
-static htab_t demangled_table;
-
-/* Look up an entry in the demangled name hash table. */
-
-static struct demangled_hash_entry *
-demangled_hash_lookup (const char *string, int create)
-{
- void **e;
- e = htab_find_slot_with_hash (demangled_table, string,
- (*htab_hash_string) (string),
- create ? INSERT : NO_INSERT);
- if (e == NULL)
- return NULL;
- if (*e == NULL)
- {
- struct demangled_hash_entry *v;
- *e = v = XCNEW (struct demangled_hash_entry);
- v->key = xstrdup (string);
- }
- return (struct demangled_hash_entry *) *e;
-}
-\f
-/* Stack code. */
-
-struct symbol_stack_entry
-{
- symbol *value;
- struct symbol_stack_entry *next;
-};
-struct obstack symbol_stack_obstack;
-struct symbol_stack_entry *symbol_stack;
-
-struct file_stack_entry
-{
- file *value;
- struct file_stack_entry *next;
-};
-struct obstack file_stack_obstack;
-struct file_stack_entry *file_stack;
-
-static void
-symbol_push (symbol *p)
-{
- struct symbol_stack_entry *ep
- = XOBNEW (&symbol_stack_obstack, struct symbol_stack_entry);
- ep->value = p;
- ep->next = symbol_stack;
- symbol_stack = ep;
-}
-
-static symbol *
-symbol_pop (void)
-{
- struct symbol_stack_entry *ep = symbol_stack;
- symbol *p;
- if (ep == NULL)
- return NULL;
- p = ep->value;
- symbol_stack = ep->next;
- obstack_free (&symbol_stack_obstack, ep);
- return p;
-}
-
-static void
-file_push (file *p)
-{
- struct file_stack_entry *ep;
-
- if (p->tweaking)
- return;
-
- ep = XOBNEW (&file_stack_obstack, struct file_stack_entry);
- ep->value = p;
- ep->next = file_stack;
- file_stack = ep;
- p->tweaking = 1;
-}
-
-static file *
-file_pop (void)
-{
- struct file_stack_entry *ep = file_stack;
- file *p;
- if (ep == NULL)
- return NULL;
- p = ep->value;
- file_stack = ep->next;
- obstack_free (&file_stack_obstack, ep);
- p->tweaking = 0;
- return p;
-}
-\f
-/* Other machinery. */
-
-/* Initialize the tlink machinery. Called from do_tlink. */
-
-static void
-tlink_init (void)
-{
- const char *p;
-
- symbol_table = htab_create (500, hash_string_hash, hash_string_eq,
- NULL);
- file_table = htab_create (500, hash_string_hash, hash_string_eq,
- NULL);
- demangled_table = htab_create (500, hash_string_hash, hash_string_eq,
- NULL);
-
- obstack_begin (&symbol_stack_obstack, 0);
- obstack_begin (&file_stack_obstack, 0);
-
- p = getenv ("TLINK_VERBOSE");
- if (p)
- tlink_verbose = atoi (p);
- else
- {
- tlink_verbose = 1;
- if (verbose)
- tlink_verbose = 2;
- if (debug)
- tlink_verbose = 3;
- }
-
- initial_cwd = getpwd ();
-}
-
-static int
-tlink_execute (const char *prog, char **argv, const char *outname,
- const char *errname, bool use_atfile)
-{
- struct pex_obj *pex;
-
- pex = collect_execute (prog, argv, outname, errname,
- PEX_LAST | PEX_SEARCH, use_atfile);
- return collect_wait (prog, pex);
-}
-
-static char *
-frob_extension (const char *s, const char *ext)
-{
- const char *p;
-
- p = strrchr (lbasename (s), '.');
- if (! p)
- p = s + strlen (s);
-
- obstack_grow (&temporary_obstack, s, p - s);
- return (char *) obstack_copy0 (&temporary_obstack, ext, strlen (ext));
-}
-
-static char *
-obstack_fgets (FILE *stream, struct obstack *ob)
-{
- int c;
- while ((c = getc (stream)) != EOF && c != '\n')
- obstack_1grow (ob, c);
- if (obstack_object_size (ob) == 0)
- return NULL;
- obstack_1grow (ob, '\0');
- return XOBFINISH (ob, char *);
-}
-
-static char *
-tfgets (FILE *stream)
-{
- return obstack_fgets (stream, &temporary_obstack);
-}
-
-static char *
-pfgets (FILE *stream)
-{
- return xstrdup (tfgets (stream));
-}
-\f
-/* Real tlink code. */
-
-/* Subroutine of read_repo_file. We are reading the repo file for file F,
- which is coming in on STREAM, and the symbol that comes next in STREAM
- is offered, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
-
- XXX "provided" is unimplemented, both here and in the compiler. */
-
-static void
-freadsym (FILE *stream, file *f, int chosen)
-{
- symbol *sym;
-
- {
- const char *name = tfgets (stream);
- sym = symbol_hash_lookup (name, true);
- }
-
- if (sym->file == NULL)
- {
- /* We didn't have this symbol already, so we choose this file. */
-
- symbol_push (sym);
- sym->file = f;
- sym->chosen = chosen;
- }
- else if (chosen)
- {
- /* We want this file; cast aside any pretender. */
-
- if (sym->chosen && sym->file != f)
- {
- if (sym->chosen == 1)
- file_push (sym->file);
- else
- {
- file_push (f);
- f = sym->file;
- chosen = sym->chosen;
- }
- }
- sym->file = f;
- sym->chosen = chosen;
- }
-}
-
-/* Read in the repo file denoted by F, and record all its information. */
-
-static void
-read_repo_file (file *f)
-{
- char c;
- FILE *stream = fopen (f->key, "r");
-
- if (tlink_verbose >= 2)
- fprintf (stderr, _("collect: reading %s\n"), f->key);
-
- while (fscanf (stream, "%c ", &c) == 1)
- {
- switch (c)
- {
- case 'A':
- f->args = pfgets (stream);
- break;
- case 'D':
- f->dir = pfgets (stream);
- break;
- case 'M':
- f->main = pfgets (stream);
- break;
- case 'P':
- freadsym (stream, f, 2);
- break;
- case 'C':
- freadsym (stream, f, 1);
- break;
- case 'O':
- freadsym (stream, f, 0);
- break;
- }
- obstack_free (&temporary_obstack, temporary_firstobj);
- }
- fclose (stream);
- if (f->args == NULL)
- f->args = getenv ("COLLECT_GCC_OPTIONS");
- if (f->dir == NULL)
- f->dir = ".";
-}
-
-/* We might want to modify LINE, which is a symbol line from file F. We do
- this if either we saw an error message referring to the symbol in
- question, or we have already allocated the symbol to another file and
- this one wants to emit it as well. */
-
-static void
-maybe_tweak (char *line, file *f)
-{
- symbol *sym = symbol_hash_lookup (line + 2, false);
-
- if ((sym->file == f && sym->tweaking)
- || (sym->file != f && line[0] == 'C'))
- {
- sym->tweaking = 0;
- sym->tweaked = 1;
-
- if (line[0] == 'O')
- {
- line[0] = 'C';
- sym->chosen = 1;
- }
- else
- {
- line[0] = 'O';
- sym->chosen = 0;
- }
- }
-}
-
-/* Update the repo files for each of the object files we have adjusted and
- recompile. */
-
-static int
-recompile_files (void)
-{
- file *f;
-
- putenv (xstrdup ("COMPILER_PATH="));
- putenv (xstrdup ("LIBRARY_PATH="));
-
- while ((f = file_pop ()) != NULL)
- {
- char *line;
- const char *p, *q;
- char **argv;
- struct obstack arg_stack;
- FILE *stream = fopen (f->key, "r");
- const char *const outname = frob_extension (f->key, ".rnw");
- FILE *output = fopen (outname, "w");
-
- while ((line = tfgets (stream)) != NULL)
- {
- switch (line[0])
- {
- case 'C':
- case 'O':
- maybe_tweak (line, f);
- }
- fprintf (output, "%s\n", line);
- }
- fclose (stream);
- fclose (output);
- /* 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_error (input_location,
- "removing repository file %qs: %m", f->key);
- if (rename (outname, f->key) == -1)
- fatal_error (input_location, "renaming repository file from "
- "%qs to %qs: %m", outname, f->key);
-
- if (!f->args)
- {
- error ("repository file %qs does not contain command-line "
- "arguments", f->key);
- return 0;
- }
-
- /* Build a null-terminated argv array suitable for
- tlink_execute(). Manipulate arguments on the arg_stack while
- building argv on the temporary_obstack. */
-
- obstack_init (&arg_stack);
- obstack_ptr_grow (&temporary_obstack, c_file_name);
-
- for (p = f->args; *p != '\0'; p = q + 1)
- {
- /* Arguments are delimited by single-quotes. Find the
- opening quote. */
- p = strchr (p, '\'');
- if (!p)
- goto done;
-
- /* Find the closing quote. */
- q = strchr (p + 1, '\'');
- if (!q)
- goto done;
-
- obstack_grow (&arg_stack, p + 1, q - (p + 1));
-
- /* Replace '\'' with '. This is how set_collect_gcc_options
- encodes a single-quote. */
- while (q[1] == '\\' && q[2] == '\'' && q[3] == '\'')
- {
- const char *r;
-
- r = strchr (q + 4, '\'');
- if (!r)
- goto done;
-
- obstack_grow (&arg_stack, q + 3, r - (q + 3));
- q = r;
- }
-
- obstack_1grow (&arg_stack, '\0');
- obstack_ptr_grow (&temporary_obstack, obstack_finish (&arg_stack));
- }
- done:
- obstack_ptr_grow (&temporary_obstack, f->main);
- obstack_ptr_grow (&temporary_obstack, NULL);
- 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, NULL, false) != 0
- || chdir (initial_cwd) != 0)
- return 0;
-
- read_repo_file (f);
-
- obstack_free (&arg_stack, NULL);
- obstack_free (&temporary_obstack, temporary_firstobj);
- }
- return 1;
-}
-
-/* The first phase of processing: determine which object files have
- .rpo files associated with them, and read in the information. */
-
-static int
-read_repo_files (char **object_lst)
-{
- char **object = object_lst;
-
- for (; *object; object++)
- {
- const char *p;
- file *f;
-
- /* Don't bother trying for ld flags. */
- if (*object[0] == '-')
- continue;
-
- p = frob_extension (*object, ".rpo");
-
- if (! file_exists (p))
- continue;
-
- f = file_hash_lookup (p);
-
- read_repo_file (f);
- }
-
- if (file_stack != NULL && ! recompile_files ())
- return 0;
-
- return (symbol_stack != NULL);
-}
-
-/* Add the demangled forms of any new symbols to the hash table. */
-
-static void
-demangle_new_symbols (void)
-{
- symbol *sym;
-
- while ((sym = symbol_pop ()) != NULL)
- {
- demangled *dem;
- const char *p = cplus_demangle (sym->key, DMGL_PARAMS | DMGL_ANSI);
-
- if (! p)
- continue;
-
- dem = demangled_hash_lookup (p, true);
- dem->mangled.safe_push (sym->key);
- }
-}
-
-/* We want to tweak symbol SYM. Return true if all is well, false on
- error. */
-
-static bool
-start_tweaking (symbol *sym)
-{
- if (sym && sym->tweaked)
- {
- error ("%qs was assigned to %qs, but was not defined "
- "during recompilation, or vice versa",
- sym->key, sym->file->key);
- return 0;
- }
- if (sym && !sym->tweaking)
- {
- if (tlink_verbose >= 2)
- fprintf (stderr, _("collect: tweaking %s in %s\n"),
- sym->key, sym->file->key);
- sym->tweaking = 1;
- file_push (sym->file);
- }
- return true;
-}
-
-/* Step through the output of the linker, in the file named FNAME, and
- adjust the settings for each symbol encountered. */
-
-static int
-scan_linker_output (const char *fname)
-{
- FILE *stream = fopen (fname, "r");
- char *line;
- int skip_next_in_line = 0;
-
- while ((line = tfgets (stream)) != NULL)
- {
- char *p = line, *q;
- symbol *sym;
- demangled *dem = 0;
- int end;
- int ok = 0;
- unsigned ix;
- str s;
-
- /* On darwin9, we might have to skip " in " lines as well. */
- if (skip_next_in_line
- && strstr (p, " in "))
- continue;
- skip_next_in_line = 0;
-
- while (*p && ISSPACE ((unsigned char) *p))
- ++p;
-
- if (! *p)
- continue;
-
- for (q = p; *q && ! ISSPACE ((unsigned char) *q); ++q)
- ;
-
- /* Try the first word on the line. */
- if (*p == '.')
- ++p;
- if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
- p += strlen (USER_LABEL_PREFIX);
-
- end = ! *q;
- *q = 0;
- sym = symbol_hash_lookup (p, false);
-
- /* Some SVR4 linkers produce messages like
- ld: 0711-317 ERROR: Undefined symbol: .g__t3foo1Zi
- */
- if (! sym && ! end && strstr (q + 1, "Undefined symbol: "))
- {
- char *p = strrchr (q + 1, ' ');
- p++;
- if (*p == '.')
- p++;
- if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
- p += strlen (USER_LABEL_PREFIX);
- sym = symbol_hash_lookup (p, false);
- }
-
- if (! sym && ! end)
- /* Try a mangled name in quotes. */
- {
- char *oldq = q + 1;
- q = 0;
-
- /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\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
- following lines with " in ". */
- skip_next_in_line = 1;
- }
-
- /* First try `GNU style'. */
- p = strchr (oldq, '`');
- if (p)
- p++, q = strchr (p, '\'');
- /* Then try "double quotes". */
- else if (p = strchr (oldq, '"'), p)
- p++, q = strchr (p, '"');
- /* Then try 'single quotes'. */
- else if (p = strchr (oldq, '\''), p)
- p++, q = strchr (p, '\'');
- else {
- /* Then try entire line. */
- q = strchr (oldq, 0);
- if (q != oldq)
- p = (char *)oldq;
- }
-
- if (p)
- {
- /* Don't let the strstr's below see the demangled name; we
- might get spurious matches. */
- p[-1] = '\0';
-
- /* powerpc64-linux references .foo when calling function foo. */
- if (*p == '.')
- p++;
- }
-
- /* We need to check for certain error keywords here, or we would
- mistakenly use GNU ld's "In function `foo':" message. */
- if (q && (ok
- || strstr (oldq, "ndefined")
- || strstr (oldq, "nresolved")
- || strstr (oldq, "nsatisfied")
- || strstr (oldq, "ultiple")))
- {
- *q = 0;
- dem = demangled_hash_lookup (p, false);
- if (!dem)
- {
- if (!strncmp (p, USER_LABEL_PREFIX,
- strlen (USER_LABEL_PREFIX)))
- p += strlen (USER_LABEL_PREFIX);
- sym = symbol_hash_lookup (p, false);
- }
- }
- }
-
- if (dem)
- {
- /* We found a demangled name. If this is the name of a
- constructor or destructor, there can be several mangled names
- that match it, so choose or unchoose all of them. If some are
- chosen and some not, leave the later ones that don't match
- alone for now; either this will cause the link to succeed, or
- on the next attempt we will switch all of them the other way
- and that will cause it to succeed. */
- int chosen = 0;
- int len = dem->mangled.length ();
- ok = true;
- FOR_EACH_VEC_ELT (dem->mangled, ix, s)
- {
- sym = symbol_hash_lookup (s, false);
- if (ix == 0)
- chosen = sym->chosen;
- else if (sym->chosen != chosen)
- /* Mismatch. */
- continue;
- /* Avoid an error about re-tweaking when we guess wrong in
- the case of mismatch. */
- if (len > 1)
- sym->tweaked = false;
- ok = start_tweaking (sym);
- }
- }
- else
- ok = start_tweaking (sym);
-
- obstack_free (&temporary_obstack, temporary_firstobj);
-
- if (!ok)
- {
- fclose (stream);
- return 0;
- }
- }
-
- fclose (stream);
- return (file_stack != NULL);
-}
-
-/* Entry point for tlink. Called from main in collect2.c.
-
- Iteratively try to provide definitions for all the unresolved symbols
- mentioned in the linker error messages.
-
- LD_ARGV is an array of arguments for the linker.
- OBJECT_LST is an array of object files that we may be able to recompile
- to provide missing definitions. Currently ignored. */
-
-void
-do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
-{
- int ret = tlink_execute ("ld", ld_argv, ldout, lderrout,
- HAVE_GNU_LD && at_file_supplied);
-
- tlink_init ();
-
- if (ret)
- {
- int i = 0;
-
- /* Until collect does a better job of figuring out which are object
- files, assume that everything on the command line could be. */
- if (read_repo_files (ld_argv))
- while (ret && i++ < MAX_ITERATIONS)
- {
- if (tlink_verbose >= 3)
- {
- dump_ld_file (ldout, stdout);
- dump_ld_file (lderrout, stderr);
- }
- demangle_new_symbols ();
- if (! scan_linker_output (ldout)
- && ! scan_linker_output (lderrout))
- break;
- if (! recompile_files ())
- break;
- if (tlink_verbose)
- fprintf (stderr, _("collect: relinking\n"));
- ret = tlink_execute ("ld", ld_argv, ldout, lderrout,
- HAVE_GNU_LD && at_file_supplied);
- }
- }
-
- dump_ld_file (ldout, stdout);
- unlink (ldout);
- dump_ld_file (lderrout, stderr);
- unlink (lderrout);
- if (ret)
- {
- error ("ld returned %d exit status", ret);
- exit (ret);
- }
- else
- {
- /* We have just successfully produced an output file, so assume that we
- may unlink it if need be for now on. */
- may_unlink_output_file = true;
- }
-}