OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [cp/] [repo.c] - Blame information for rev 283

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 283 jeremybenn
/* Code to maintain a C++ template repository.
2
   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2006, 2007, 2008  Free Software Foundation, Inc.
4
   Contributed by Jason Merrill (jason@cygnus.com)
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3, or (at your option)
11
any later version.
12
 
13
GCC is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
/* My strategy here is as follows:
23
 
24
   Everything should be emitted in a translation unit where it is used.
25
   The results of the automatic process should be easily reproducible with
26
   explicit code.  */
27
 
28
#include "config.h"
29
#include "system.h"
30
#include "coretypes.h"
31
#include "tm.h"
32
#include "tree.h"
33
#include "cp-tree.h"
34
#include "input.h"
35
#include "obstack.h"
36
#include "toplev.h"
37
#include "diagnostic.h"
38
#include "flags.h"
39
 
40
static const char *extract_string (const char **);
41
static const char *get_base_filename (const char *);
42
static FILE *open_repo_file (const char *);
43
static char *afgets (FILE *);
44
static FILE *reopen_repo_file_for_write (void);
45
 
46
static GTY(()) tree pending_repo;
47
static char *repo_name;
48
 
49
static const char *old_args, *old_dir, *old_main;
50
 
51
static struct obstack temporary_obstack;
52
static bool temporary_obstack_initialized_p;
53
 
54
/* Parse a reasonable subset of shell quoting syntax.  */
55
 
56
static const char *
57
extract_string (const char **pp)
58
{
59
  const char *p = *pp;
60
  int backquote = 0;
61
  int inside = 0;
62
 
63
  for (;;)
64
    {
65
      char c = *p;
66
      if (c == '\0')
67
        break;
68
      ++p;
69
      if (backquote)
70
        {
71
          obstack_1grow (&temporary_obstack, c);
72
          backquote = 0;
73
        }
74
      else if (! inside && c == ' ')
75
        break;
76
      else if (! inside && c == '\\')
77
        backquote = 1;
78
      else if (c == '\'')
79
        inside = !inside;
80
      else
81
        obstack_1grow (&temporary_obstack, c);
82
    }
83
 
84
  obstack_1grow (&temporary_obstack, '\0');
85
  *pp = p;
86
  return (char *) obstack_finish (&temporary_obstack);
87
}
88
 
89
static const char *
90
get_base_filename (const char *filename)
91
{
92
  const char *p = getenv ("COLLECT_GCC_OPTIONS");
93
  const char *output = NULL;
94
  int compiling = 0;
95
 
96
  while (p && *p)
97
    {
98
      const char *q = extract_string (&p);
99
 
100
      if (strcmp (q, "-o") == 0)
101
        {
102
          if (flag_compare_debug)
103
            /* Just in case aux_base_name was based on a name with two
104
               or more '.'s, add an arbitrary extension that will be
105
               stripped by the caller.  */
106
            output = concat (aux_base_name, ".o", NULL);
107
          else
108
            output = extract_string (&p);
109
        }
110
      else if (strcmp (q, "-c") == 0)
111
        compiling = 1;
112
    }
113
 
114
  if (compiling && output)
115
    return output;
116
 
117
  if (p && ! compiling)
118
    {
119
      warning (0, "-frepo must be used with -c");
120
      flag_use_repository = 0;
121
      return NULL;
122
    }
123
 
124
  return lbasename (filename);
125
}
126
 
127
static FILE *
128
open_repo_file (const char *filename)
129
{
130
  const char *p;
131
  const char *s = get_base_filename (filename);
132
 
133
  if (s == NULL)
134
    return NULL;
135
 
136
  p = lbasename (s);
137
  p = strrchr (p, '.');
138
  if (! p)
139
    p = s + strlen (s);
140
 
141
  repo_name = XNEWVEC (char, p - s + 5);
142
  memcpy (repo_name, s, p - s);
143
  memcpy (repo_name + (p - s), ".rpo", 5);
144
 
145
  return fopen (repo_name, "r");
146
}
147
 
148
static char *
149
afgets (FILE *stream)
150
{
151
  int c;
152
  while ((c = getc (stream)) != EOF && c != '\n')
153
    obstack_1grow (&temporary_obstack, c);
154
  if (obstack_object_size (&temporary_obstack) == 0)
155
    return NULL;
156
  obstack_1grow (&temporary_obstack, '\0');
157
  return (char *) obstack_finish (&temporary_obstack);
158
}
159
 
160
void
161
init_repo (void)
162
{
163
  char *buf;
164
  const char *p;
165
  FILE *repo_file;
166
 
167
  if (! flag_use_repository)
168
    return;
169
 
170
  /* When a PCH file is loaded, the entire identifier table is
171
     replaced, with the result that IDENTIFIER_REPO_CHOSEN is cleared.
172
     So, we have to reread the repository file.  */
173
  lang_post_pch_load = init_repo;
174
 
175
  if (!temporary_obstack_initialized_p)
176
    gcc_obstack_init (&temporary_obstack);
177
 
178
  repo_file = open_repo_file (main_input_filename);
179
 
180
  if (repo_file == 0)
181
    return;
182
 
183
  while ((buf = afgets (repo_file)))
184
    {
185
      switch (buf[0])
186
        {
187
        case 'A':
188
          old_args = ggc_strdup (buf + 2);
189
          break;
190
        case 'D':
191
          old_dir = ggc_strdup (buf + 2);
192
          break;
193
        case 'M':
194
          old_main = ggc_strdup (buf + 2);
195
          break;
196
        case 'O':
197
          /* A symbol that we were able to define the last time this
198
             file was compiled.  */
199
          break;
200
        case 'C':
201
          /* A symbol that the prelinker has requested that we
202
             define.  */
203
          {
204
            tree id = get_identifier (buf + 2);
205
            IDENTIFIER_REPO_CHOSEN (id) = 1;
206
          }
207
          break;
208
        default:
209
          error ("mysterious repository information in %s", repo_name);
210
        }
211
      obstack_free (&temporary_obstack, buf);
212
    }
213
  fclose (repo_file);
214
 
215
  if (old_args && !get_random_seed (true)
216
      && (p = strstr (old_args, "'-frandom-seed=")))
217
    set_random_seed (extract_string (&p) + strlen ("-frandom-seed="));
218
}
219
 
220
static FILE *
221
reopen_repo_file_for_write (void)
222
{
223
  FILE *repo_file = fopen (repo_name, "w");
224
 
225
  if (repo_file == 0)
226
    {
227
      error ("can't create repository information file %qs", repo_name);
228
      flag_use_repository = 0;
229
    }
230
 
231
  return repo_file;
232
}
233
 
234
/* Emit any pending repos.  */
235
 
236
void
237
finish_repo (void)
238
{
239
  tree t;
240
  char *dir, *args;
241
  FILE *repo_file;
242
 
243
  if (!flag_use_repository || flag_compare_debug)
244
    return;
245
 
246
  if (errorcount || sorrycount)
247
    return;
248
 
249
  repo_file = reopen_repo_file_for_write ();
250
  if (repo_file == 0)
251
    goto out;
252
 
253
  fprintf (repo_file, "M %s\n", main_input_filename);
254
  dir = getpwd ();
255
  fprintf (repo_file, "D %s\n", dir);
256
  args = getenv ("COLLECT_GCC_OPTIONS");
257
  if (args)
258
    {
259
      fprintf (repo_file, "A %s", args);
260
      /* If -frandom-seed is not among the ARGS, then add the value
261
         that we chose.  That will ensure that the names of types from
262
         anonymous namespaces will get the same mangling when this
263
         file is recompiled.  */
264
      if (!strstr (args, "'-frandom-seed="))
265
        fprintf (repo_file, " '-frandom-seed=%s'", get_random_seed (false));
266
      fprintf (repo_file, "\n");
267
    }
268
 
269
  for (t = pending_repo; t; t = TREE_CHAIN (t))
270
    {
271
      tree val = TREE_VALUE (t);
272
      tree name = DECL_ASSEMBLER_NAME (val);
273
      char type = IDENTIFIER_REPO_CHOSEN (name) ? 'C' : 'O';
274
      fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (name));
275
    }
276
 
277
 out:
278
  if (repo_file)
279
    fclose (repo_file);
280
}
281
 
282
/* DECL is a FUNCTION_DECL or VAR_DECL with vague linkage whose
283
   definition is available in this translation unit.  Returns 0 if
284
   this definition should not be emitted in this translation unit
285
   because it will be emitted elsewhere.  Returns 1 if the repository
286
   file indicates that that DECL should be emitted in this translation
287
   unit, or 2 if the repository file is not in use.  */
288
 
289
int
290
repo_emit_p (tree decl)
291
{
292
  int ret = 0;
293
  gcc_assert (TREE_PUBLIC (decl));
294
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
295
              || TREE_CODE (decl) == VAR_DECL);
296
  gcc_assert (!DECL_REALLY_EXTERN (decl));
297
 
298
  /* When not using the repository, emit everything.  */
299
  if (!flag_use_repository)
300
    return 2;
301
 
302
  /* Only template instantiations are managed by the repository.  This
303
     is an artificial restriction; the code in the prelinker and here
304
     will work fine if all entities with vague linkage are managed by
305
     the repository.  */
306
  if (TREE_CODE (decl) == VAR_DECL)
307
    {
308
      tree type = NULL_TREE;
309
      if (DECL_VTABLE_OR_VTT_P (decl))
310
        type = DECL_CONTEXT (decl);
311
      else if (DECL_TINFO_P (decl))
312
        type = TREE_TYPE (DECL_NAME (decl));
313
      if (!DECL_TEMPLATE_INSTANTIATION (decl)
314
          && (!TYPE_LANG_SPECIFIC (type)
315
              || !CLASSTYPE_TEMPLATE_INSTANTIATION (type)))
316
        return 2;
317
      /* Const static data members initialized by constant expressions must
318
         be processed where needed so that their definitions are
319
         available.  Still record them into *.rpo files, so if they
320
         weren't actually emitted and collect2 requests them, they can
321
         be provided.  */
322
      if (DECL_INTEGRAL_CONSTANT_VAR_P (decl)
323
          && DECL_CLASS_SCOPE_P (decl))
324
        ret = 2;
325
    }
326
  else if (!DECL_TEMPLATE_INSTANTIATION (decl))
327
    return 2;
328
 
329
  if (DECL_EXPLICIT_INSTANTIATION (decl))
330
    return 2;
331
 
332
  /* For constructors and destructors, the repository contains
333
     information about the clones -- not the original function --
334
     because only the clones are emitted in the object file.  */
335
  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
336
      || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
337
    {
338
      int emit_p = 0;
339
      tree clone;
340
      /* There is no early exit from this loop because we want to
341
         ensure that all of the clones are marked as available in this
342
         object file.  */
343
      FOR_EACH_CLONE (clone, decl)
344
        /* The only possible results from the recursive call to
345
           repo_emit_p are 0 or 1.  */
346
        if (repo_emit_p (clone))
347
          emit_p = 1;
348
      return emit_p;
349
    }
350
 
351
  /* Keep track of all available entities.  */
352
  if (!DECL_REPO_AVAILABLE_P (decl))
353
    {
354
      DECL_REPO_AVAILABLE_P (decl) = 1;
355
      pending_repo = tree_cons (NULL_TREE, decl, pending_repo);
356
    }
357
 
358
  return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret;
359
}
360
 
361
/* Returns true iff the prelinker has explicitly marked CLASS_TYPE for
362
   export from this translation unit.  */
363
 
364
bool
365
repo_export_class_p (const_tree class_type)
366
{
367
  if (!flag_use_repository)
368
    return false;
369
  if (!CLASSTYPE_VTABLES (class_type))
370
    return false;
371
  /* If the virtual table has been assigned to this translation unit,
372
     export the class.  */
373
  return (IDENTIFIER_REPO_CHOSEN
374
          (DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (class_type))));
375
}
376
 
377
#include "gt-cp-repo.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.