OSDN Git Service

Eliminate the computed goto in x64 varargs.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / winnt.c
1 /* Subroutines for insn-output.c for Windows NT.
2    Contributed by Douglas Rupp (drupp@cs.washington.edu)
3    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4    2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 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 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "output.h"
30 #include "tree.h"
31 #include "flags.h"
32 #include "tm_p.h"
33 #include "diagnostic-core.h"
34 #include "toplev.h"
35 #include "hashtab.h"
36 #include "langhooks.h"
37 #include "ggc.h"
38 #include "target.h"
39 #include "lto-streamer.h"
40
41 /* i386/PE specific attribute support.
42
43    i386/PE has two new attributes:
44    dllexport - for exporting a function/variable that will live in a dll
45    dllimport - for importing a function/variable from a dll
46
47    Microsoft allows multiple declspecs in one __declspec, separating
48    them with spaces.  We do NOT support this.  Instead, use __declspec
49    multiple times.
50 */
51
52 /* Handle a "shared" attribute;
53    arguments as in struct attribute_spec.handler.  */
54 tree
55 ix86_handle_shared_attribute (tree *node, tree name,
56                               tree args ATTRIBUTE_UNUSED,
57                               int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
58 {
59   if (TREE_CODE (*node) != VAR_DECL)
60     {
61       warning (OPT_Wattributes, "%qE attribute only applies to variables",
62                name);
63       *no_add_attrs = true;
64     }
65
66   return NULL_TREE;
67 }
68
69 /* Handle a "selectany" attribute;
70    arguments as in struct attribute_spec.handler.  */
71 tree
72 ix86_handle_selectany_attribute (tree *node, tree name,
73                                  tree args ATTRIBUTE_UNUSED,
74                                  int flags ATTRIBUTE_UNUSED,
75                                  bool *no_add_attrs)
76 {
77   /* The attribute applies only to objects that are initialized and have
78      external linkage.  However, we may not know about initialization
79      until the language frontend has processed the decl. We'll check for
80      initialization later in encode_section_info.  */
81   if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
82     {   
83       error ("%qE attribute applies only to initialized variables"
84              " with external linkage", name);
85       *no_add_attrs = true;
86     }
87
88   return NULL_TREE;
89 }
90
91 \f
92 /* Return the type that we should use to determine if DECL is
93    imported or exported.  */
94
95 static tree
96 associated_type (tree decl)
97 {
98   return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
99           ?  DECL_CONTEXT (decl) : NULL_TREE);
100 }
101
102 /* Return true if DECL should be a dllexport'd object.  */
103
104 static bool
105 i386_pe_determine_dllexport_p (tree decl)
106 {
107   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
108     return false;
109
110   /* Don't export local clones of dllexports.  */
111   if (!TREE_PUBLIC (decl))
112     return false;
113
114   if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
115     return true;
116
117   return false;
118 }
119
120 /* Return true if DECL should be a dllimport'd object.  */
121
122 static bool
123 i386_pe_determine_dllimport_p (tree decl)
124 {
125   tree assoc;
126
127   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
128     return false;
129
130   if (DECL_DLLIMPORT_P (decl))
131     return true;
132
133   /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
134      by  targetm.cxx.adjust_class_at_definition.  Check again to emit
135      error message if the class attribute has been overridden by an
136      out-of-class definition of static data.  */
137   assoc = associated_type (decl);
138   if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))
139       && TREE_CODE (decl) == VAR_DECL
140       && TREE_STATIC (decl) && TREE_PUBLIC (decl)
141       && !DECL_EXTERNAL (decl)
142       /* vtable's are linkonce constants, so defining a vtable is not
143          an error as long as we don't try to import it too.  */
144       && !DECL_VIRTUAL_P (decl))
145         error ("definition of static data member %q+D of "
146                "dllimport'd class", decl);
147
148   return false;
149 }
150
151 /* Handle the -mno-fun-dllimport target switch.  */
152
153 bool
154 i386_pe_valid_dllimport_attribute_p (const_tree decl)
155 {
156    if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
157      return false;
158    return true;
159 }
160
161 /* Return string which is the function name, identified by ID, modified
162    with a suffix consisting of an atsign (@) followed by the number of
163    bytes of arguments.  If ID is NULL use the DECL_NAME as base. If
164    FASTCALL is true, also add the FASTCALL_PREFIX.
165    Return NULL if no change required.  */
166
167 static tree
168 gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
169 {
170   HOST_WIDE_INT total = 0;
171   const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
172   char *new_str, *p;
173   tree type = TREE_TYPE (decl);
174   tree arg;
175   function_args_iterator args_iter;
176
177   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);  
178
179   if (prototype_p (type))
180     {
181       /* This attribute is ignored for variadic functions.  */ 
182       if (stdarg_p (type))
183         return NULL_TREE;
184
185       /* Quit if we hit an incomplete type.  Error is reported
186          by convert_arguments in c-typeck.c or cp/typeck.c.  */
187       FOREACH_FUNCTION_ARGS(type, arg, args_iter)
188         {
189           HOST_WIDE_INT parm_size;
190           HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
191
192           if (! COMPLETE_TYPE_P (arg))
193             break;
194
195           parm_size = int_size_in_bytes (arg);
196           if (parm_size < 0)
197             break;
198
199           /* Must round up to include padding.  This is done the same
200              way as in store_one_arg.  */
201           parm_size = ((parm_size + parm_boundary_bytes - 1)
202                        / parm_boundary_bytes * parm_boundary_bytes);
203           total += parm_size;
204         }
205       }
206   /* Assume max of 8 base 10 digits in the suffix.  */
207   p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1);
208   if (fastcall)
209     *p++ = FASTCALL_PREFIX;
210   sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total);
211
212   return get_identifier (new_str);
213 }
214
215 /* Maybe decorate and get a new identifier for the DECL of a stdcall or
216    fastcall function. The original identifier is supplied in ID. */
217
218 static tree
219 i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id)
220 {
221   tree new_id = NULL_TREE;
222
223   if (TREE_CODE (decl) == FUNCTION_DECL)
224     { 
225       tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
226       if (lookup_attribute ("stdcall", type_attributes))
227         new_id = gen_stdcall_or_fastcall_suffix (decl, id, false);
228       else if (lookup_attribute ("fastcall", type_attributes))
229         new_id = gen_stdcall_or_fastcall_suffix (decl, id, true);
230     }
231
232   return new_id;
233 }
234
235 /* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
236    in the language-independent default hook
237    langhooks,c:lhd_set_decl_assembler_name ()
238    and in cp/mangle,c:mangle_decl ().  */
239 tree
240 i386_pe_mangle_decl_assembler_name (tree decl, tree id)
241 {
242   tree new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, id);   
243
244   return (new_id ? new_id : id);
245 }
246
247 void
248 i386_pe_encode_section_info (tree decl, rtx rtl, int first)
249 {
250   rtx symbol;
251   int flags;
252
253   /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above.  */
254   default_encode_section_info (decl, rtl, first);
255
256   /* Careful not to prod global register variables.  */
257   if (!MEM_P (rtl))
258     return;
259
260   symbol = XEXP (rtl, 0);
261   gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
262
263   switch (TREE_CODE (decl))
264     {
265     case FUNCTION_DECL:
266       /* FIXME:  Imported stdcall names are not modified by the Ada frontend.
267          Check and decorate the RTL name now.  */
268       if  (strcmp (lang_hooks.name, "GNU Ada") == 0)
269         {
270           tree new_id;
271           tree old_id = DECL_ASSEMBLER_NAME (decl);
272           const char* asm_str = IDENTIFIER_POINTER (old_id);
273           /* Do not change the identifier if a verbatim asmspec
274              or if stdcall suffix already added. */
275           if (!(*asm_str == '*' || strchr (asm_str, '@'))
276               && (new_id = i386_pe_maybe_mangle_decl_assembler_name (decl,
277                                                                      old_id)))
278             XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id);
279         }
280       break;
281
282     case VAR_DECL:
283       if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
284         {
285           if (DECL_INITIAL (decl)
286               /* If an object is initialized with a ctor, the static
287                  initialization and destruction code for it is present in
288                  each unit defining the object.  The code that calls the
289                  ctor is protected by a link-once guard variable, so that
290                  the object still has link-once semantics,  */
291               || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
292             make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
293           else
294             error ("%q+D:'selectany' attribute applies only to "
295                    "initialized objects", decl);
296         }
297       break;
298
299     default:
300       return;
301     }
302
303   /* Mark the decl so we can tell from the rtl whether the object is
304      dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
305      handles dllexport/dllimport override semantics.  */
306   flags = (SYMBOL_REF_FLAGS (symbol) &
307            ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));
308   if (i386_pe_determine_dllexport_p (decl))
309     flags |= SYMBOL_FLAG_DLLEXPORT;
310   else if (i386_pe_determine_dllimport_p (decl))
311     flags |= SYMBOL_FLAG_DLLIMPORT;
312  
313   SYMBOL_REF_FLAGS (symbol) = flags;
314 }
315
316 bool
317 i386_pe_binds_local_p (const_tree exp)
318 {
319   /* PE does not do dynamic binding.  Indeed, the only kind of
320      non-local reference comes from a dllimport'd symbol.  */
321   if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
322       && DECL_DLLIMPORT_P (exp))
323     return false;
324
325   /* Or a weak one, now that they are supported.  */
326   if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
327       && DECL_WEAK (exp))
328     /* But x64 gets confused and attempts to use unsupported GOTPCREL
329        relocations if we tell it the truth, so we still return true in
330        that case until the deeper problem can be fixed.  */
331     return (TARGET_64BIT && DEFAULT_ABI == MS_ABI);
332
333   return true;
334 }
335
336 /* Also strip the fastcall prefix and stdcall suffix.  */
337
338 const char *
339 i386_pe_strip_name_encoding_full (const char *str)
340 {
341   const char *p;
342   const char *name = default_strip_name_encoding (str);
343
344   /* Strip leading '@' on fastcall symbols.  */
345   if (*name == '@')
346     name++;
347
348   /* Strip trailing "@n".  */
349   p = strchr (name, '@');
350   if (p)
351     return ggc_alloc_string (name, p - name);
352
353   return name;
354 }
355
356 void
357 i386_pe_unique_section (tree decl, int reloc)
358 {
359   int len;
360   const char *name, *prefix;
361   char *string;
362
363   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
364   name = i386_pe_strip_name_encoding_full (name);
365
366   /* The object is put in, for example, section .text$foo.
367      The linker will then ultimately place them in .text
368      (everything from the $ on is stripped). Don't put
369      read-only data in .rdata section to avoid a PE linker
370      bug when .rdata$* grouped sections are used in code
371      without a .rdata section.  */
372   if (TREE_CODE (decl) == FUNCTION_DECL)
373     prefix = ".text$";
374   else if (decl_readonly_section (decl, reloc))
375     prefix = ".rdata$";
376   else
377     prefix = ".data$";
378   len = strlen (name) + strlen (prefix);
379   string = XALLOCAVEC (char, len + 1);
380   sprintf (string, "%s%s", prefix, name);
381
382   DECL_SECTION_NAME (decl) = build_string (len, string);
383 }
384
385 /* Select a set of attributes for section NAME based on the properties
386    of DECL and whether or not RELOC indicates that DECL's initializer
387    might contain runtime relocations.
388
389    We make the section read-only and executable for a function decl,
390    read-only for a const data decl, and writable for a non-const data decl.
391
392    If the section has already been defined, to not allow it to have
393    different attributes, as (1) this is ambiguous since we're not seeing
394    all the declarations up front and (2) some assemblers (e.g. SVR4)
395    do not recognize section redefinitions.  */
396 /* ??? This differs from the "standard" PE implementation in that we
397    handle the SHARED variable attribute.  Should this be done for all
398    PE targets?  */
399
400 #define SECTION_PE_SHARED       SECTION_MACH_DEP
401
402 unsigned int
403 i386_pe_section_type_flags (tree decl, const char *name, int reloc)
404 {
405   static htab_t htab;
406   unsigned int flags;
407   unsigned int **slot;
408
409   /* The names we put in the hashtable will always be the unique
410      versions given to us by the stringtable, so we can just use
411      their addresses as the keys.  */
412   if (!htab)
413     htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
414
415   if (decl && TREE_CODE (decl) == FUNCTION_DECL)
416     flags = SECTION_CODE;
417   else if (decl && decl_readonly_section (decl, reloc))
418     flags = 0;
419   else if (current_function_decl
420            && cfun
421            && crtl->subsections.unlikely_text_section_name
422            && strcmp (name, crtl->subsections.unlikely_text_section_name) == 0)
423     flags = SECTION_CODE;
424   else if (!decl
425            && (!current_function_decl || !cfun)
426            && strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
427     flags = SECTION_CODE;
428   else
429     {
430       flags = SECTION_WRITE;
431
432       if (decl && TREE_CODE (decl) == VAR_DECL
433           && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
434         flags |= SECTION_PE_SHARED;
435     }
436
437   if (decl && DECL_ONE_ONLY (decl))
438     flags |= SECTION_LINKONCE;
439
440   /* See if we already have an entry for this section.  */
441   slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
442   if (!*slot)
443     {
444       *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
445       **slot = flags;
446     }
447   else
448     {
449       if (decl && **slot != flags)
450         error ("%q+D causes a section type conflict", decl);
451     }
452
453   return flags;
454 }
455
456 void
457 i386_pe_asm_named_section (const char *name, unsigned int flags, 
458                            tree decl)
459 {
460   char flagchars[8], *f = flagchars;
461
462   if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
463     /* readonly data */
464     {
465       *f++ ='d';  /* This is necessary for older versions of gas.  */
466       *f++ ='r';
467     }
468   else  
469     {
470       if (flags & SECTION_CODE)
471         *f++ = 'x';
472       if (flags & SECTION_WRITE)
473         *f++ = 'w';
474       if (flags & SECTION_PE_SHARED)
475         *f++ = 's';
476     }
477
478   /* LTO sections need 1-byte alignment to avoid confusing the
479      zlib decompression algorithm with trailing zero pad bytes.  */
480   if (strncmp (name, LTO_SECTION_NAME_PREFIX,
481                         strlen (LTO_SECTION_NAME_PREFIX)) == 0)
482     *f++ = '0';
483
484   *f = '\0';
485
486   fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
487
488   if (flags & SECTION_LINKONCE)
489     {
490       /* Functions may have been compiled at various levels of
491          optimization so we can't use `same_size' here.
492          Instead, have the linker pick one, without warning.
493          If 'selectany' attribute has been specified,  MS compiler
494          sets 'discard' characteristic, rather than telling linker
495          to warn of size or content mismatch, so do the same.  */ 
496       bool discard = (flags & SECTION_CODE)
497                       || lookup_attribute ("selectany",
498                                            DECL_ATTRIBUTES (decl));      
499       fprintf (asm_out_file, "\t.linkonce %s\n",
500                (discard  ? "discard" : "same_size"));
501     }
502 }
503
504 /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker.  */
505
506 void
507 i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
508                                         const char *name, HOST_WIDE_INT size,
509                                         HOST_WIDE_INT align ATTRIBUTE_UNUSED)
510 {
511   HOST_WIDE_INT rounded;
512
513   /* Compute as in assemble_noswitch_variable, since we don't have
514      support for aligned common on older binutils.  We must also
515      avoid emitting a common symbol of size zero, as this is the
516      overloaded representation that indicates an undefined external
517      symbol in the PE object file format.  */
518   rounded = size ? size : 1;
519   rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
520   rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
521              * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
522   
523   i386_pe_maybe_record_exported_symbol (decl, name, 1);
524
525   fprintf (stream, "\t.comm\t");
526   assemble_name (stream, name);
527   if (use_pe_aligned_common)
528     fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
529            size ? size : (HOST_WIDE_INT) 1,
530            exact_log2 (align) - exact_log2 (CHAR_BIT));
531   else
532     fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
533            " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
534 }
535 \f
536 /* The Microsoft linker requires that every function be marked as
537    DT_FCN.  When using gas on cygwin, we must emit appropriate .type
538    directives.  */
539
540 #include "gsyms.h"
541
542 /* Mark a function appropriately.  This should only be called for
543    functions for which we are not emitting COFF debugging information.
544    FILE is the assembler output file, NAME is the name of the
545    function, and PUB is nonzero if the function is globally
546    visible.  */
547
548 void
549 i386_pe_declare_function_type (FILE *file, const char *name, int pub)
550 {
551   fprintf (file, "\t.def\t");
552   assemble_name (file, name);
553   fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
554            pub ? (int) C_EXT : (int) C_STAT,
555            (int) DT_FCN << N_BTSHFT);
556 }
557
558 /* Keep a list of external functions.  */
559
560 struct GTY(()) extern_list
561 {
562   struct extern_list *next;
563   tree decl;
564   const char *name;
565 };
566
567 static GTY(()) struct extern_list *extern_head;
568
569 /* Assemble an external function reference.  We need to keep a list of
570    these, so that we can output the function types at the end of the
571    assembly.  We can't output the types now, because we might see a
572    definition of the function later on and emit debugging information
573    for it then.  */
574
575 void
576 i386_pe_record_external_function (tree decl, const char *name)
577 {
578   struct extern_list *p;
579
580   p = ggc_alloc_extern_list ();
581   p->next = extern_head;
582   p->decl = decl;
583   p->name = name;
584   extern_head = p;
585 }
586
587 /* Keep a list of exported symbols.  */
588
589 struct GTY(()) export_list
590 {
591   struct export_list *next;
592   const char *name;
593   int is_data;          /* used to type tag exported symbols.  */
594 };
595
596 static GTY(()) struct export_list *export_head;
597
598 /* Assemble an export symbol entry.  We need to keep a list of
599    these, so that we can output the export list at the end of the
600    assembly.  We used to output these export symbols in each function,
601    but that causes problems with GNU ld when the sections are
602    linkonce.  Beware, DECL may be NULL if compile_file() is emitting
603    the LTO marker.  */
604
605 void
606 i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
607 {
608   rtx symbol;
609   struct export_list *p;
610
611   if (!decl)
612     return;
613
614   symbol = XEXP (DECL_RTL (decl), 0);
615   gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
616   if (!SYMBOL_REF_DLLEXPORT_P (symbol))
617     return;
618
619   gcc_assert (TREE_PUBLIC (decl));
620
621   p = ggc_alloc_export_list ();
622   p->next = export_head;
623   p->name = name;
624   p->is_data = is_data;
625   export_head = p;
626 }
627
628 #ifdef CXX_WRAP_SPEC_LIST
629
630 /*  Hash table equality helper function.  */
631
632 static int
633 wrapper_strcmp (const void *x, const void *y)
634 {
635   return !strcmp ((const char *) x, (const char *) y);
636 }
637
638 /* Search for a function named TARGET in the list of library wrappers
639    we are using, returning a pointer to it if found or NULL if not.
640    This function might be called on quite a few symbols, and we only
641    have the list of names of wrapped functions available to us as a
642    spec string, so first time round we lazily initialise a hash table
643    to make things quicker.  */
644
645 static const char *
646 i386_find_on_wrapper_list (const char *target)
647 {
648   static char first_time = 1;
649   static htab_t wrappers;
650
651   if (first_time)
652     {
653       /* Beware that this is not a complicated parser, it assumes
654          that any sequence of non-whitespace beginning with an
655          underscore is one of the wrapped symbols.  For now that's
656          adequate to distinguish symbols from spec substitutions
657          and command-line options.  */
658       static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
659       char *bufptr;
660       /* Breaks up the char array into separated strings
661          strings and enter them into the hash table.  */
662       wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
663         0, xcalloc, free);
664       for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
665         {
666           char *found = NULL;
667           if (ISSPACE (*bufptr))
668             continue;
669           if (*bufptr == '_')
670             found = bufptr;
671           while (*bufptr && !ISSPACE (*bufptr))
672             ++bufptr;
673           if (*bufptr)
674             *bufptr = 0;
675           if (found)
676             *htab_find_slot (wrappers, found, INSERT) = found;
677         }
678       first_time = 0;
679     }
680
681   return (const char *) htab_find (wrappers, target);
682 }
683
684 #endif /* CXX_WRAP_SPEC_LIST */
685
686 /* This is called at the end of assembly.  For each external function
687    which has not been defined, we output a declaration now.  We also
688    output the .drectve section.  */
689
690 void
691 i386_pe_file_end (void)
692 {
693   struct extern_list *p;
694
695   for (p = extern_head; p != NULL; p = p->next)
696     {
697       tree decl;
698
699       decl = p->decl;
700
701       /* Positively ensure only one declaration for any given symbol.  */
702       if (! TREE_ASM_WRITTEN (decl)
703           && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
704         {
705 #ifdef CXX_WRAP_SPEC_LIST
706           /* To ensure the DLL that provides the corresponding real
707              functions is still loaded at runtime, we must reference
708              the real function so that an (unused) import is created.  */
709           const char *realsym = i386_find_on_wrapper_list (p->name);
710           if (realsym)
711             i386_pe_declare_function_type (asm_out_file,
712                 concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
713 #endif /* CXX_WRAP_SPEC_LIST */
714           TREE_ASM_WRITTEN (decl) = 1;
715           i386_pe_declare_function_type (asm_out_file, p->name,
716                                          TREE_PUBLIC (decl));
717         }
718     }
719
720   if (export_head)
721     {
722       struct export_list *q;
723       drectve_section ();
724       for (q = export_head; q != NULL; q = q->next)
725         {
726           fprintf (asm_out_file, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
727                    default_strip_name_encoding (q->name),
728                    (q->is_data ? ",data" : ""));
729         }
730     }
731 }
732
733 #include "gt-winnt.h"