* config/darwin-c.c, config/arc/arc.c, config/arc/arc.md,
[official-gcc.git] / gcc / config / i386 / winnt.c
blob845960eb3e93d68ea98d0141942068554fd14f77
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 Free Software Foundation, Inc.
6 This file is part of GCC.
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 2, or (at your option) any later
11 version.
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.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "output.h"
31 #include "tree.h"
32 #include "flags.h"
33 #include "tm_p.h"
34 #include "toplev.h"
35 #include "hashtab.h"
36 #include "ggc.h"
38 /* i386/PE specific attribute support.
40 i386/PE has two new attributes:
41 dllexport - for exporting a function/variable that will live in a dll
42 dllimport - for importing a function/variable from a dll
44 Microsoft allows multiple declspecs in one __declspec, separating
45 them with spaces. We do NOT support this. Instead, use __declspec
46 multiple times.
49 static tree associated_type (tree);
50 static tree gen_stdcall_or_fastcall_suffix (tree, bool);
51 static int i386_pe_dllexport_p (tree);
52 static int i386_pe_dllimport_p (tree);
53 static void i386_pe_mark_dllexport (tree);
54 static void i386_pe_mark_dllimport (tree);
56 /* This is we how mark internal identifiers with dllimport or dllexport
57 attributes. */
58 #ifndef DLL_IMPORT_PREFIX
59 #define DLL_IMPORT_PREFIX "#i."
60 #endif
61 #ifndef DLL_EXPORT_PREFIX
62 #define DLL_EXPORT_PREFIX "#e."
63 #endif
65 /* Handle a "shared" attribute;
66 arguments as in struct attribute_spec.handler. */
67 tree
68 ix86_handle_shared_attribute (tree *node, tree name,
69 tree args ATTRIBUTE_UNUSED,
70 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
72 if (TREE_CODE (*node) != VAR_DECL)
74 warning ("`%s' attribute only applies to variables",
75 IDENTIFIER_POINTER (name));
76 *no_add_attrs = true;
79 return NULL_TREE;
82 /* Return the type that we should use to determine if DECL is
83 imported or exported. */
85 static tree
86 associated_type (tree decl)
88 tree t = NULL_TREE;
90 /* In the C++ frontend, DECL_CONTEXT for a method doesn't actually refer
91 to the containing class. So we look at the 'this' arg. */
92 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
94 /* Artificial methods are not affected by the import/export status
95 of their class unless they are COMDAT. Implicit copy ctor's and
96 dtor's are not affected by class status but virtual and
97 non-virtual thunks are. */
98 if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl))
99 t = TYPE_MAIN_VARIANT
100 (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
102 else if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
103 t = DECL_CONTEXT (decl);
105 return t;
108 /* Return nonzero if DECL is a dllexport'd object. */
110 static int
111 i386_pe_dllexport_p (tree decl)
113 tree exp;
115 if (TREE_CODE (decl) != VAR_DECL
116 && TREE_CODE (decl) != FUNCTION_DECL)
117 return 0;
118 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
119 if (exp)
120 return 1;
122 /* Class members get the dllexport status of their class. */
123 if (associated_type (decl))
125 exp = lookup_attribute ("dllexport",
126 TYPE_ATTRIBUTES (associated_type (decl)));
127 if (exp)
128 return 1;
131 return 0;
134 /* Return nonzero if DECL is a dllimport'd object. */
136 static int
137 i386_pe_dllimport_p (tree decl)
139 tree imp;
140 int context_imp = 0;
142 if (TREE_CODE (decl) == FUNCTION_DECL
143 && TARGET_NOP_FUN_DLLIMPORT)
144 return 0;
146 if (TREE_CODE (decl) != VAR_DECL
147 && TREE_CODE (decl) != FUNCTION_DECL)
148 return 0;
150 imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
152 /* Class members get the dllimport status of their class. */
153 if (!imp && associated_type (decl))
155 imp = lookup_attribute ("dllimport",
156 TYPE_ATTRIBUTES (associated_type (decl)));
157 if (imp)
158 context_imp = 1;
161 if (imp)
163 /* Don't mark defined functions as dllimport. If the definition
164 itself was marked with dllimport, than ix86_handle_dll_attribute
165 reports an error. This handles the case when the definition
166 overrides an earlier declaration. */
167 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)
168 && !DECL_INLINE (decl))
170 /* Don't warn about artificial methods. */
171 if (!DECL_ARTIFICIAL (decl))
172 warning ("%Jfunction '%D' is defined after prior declaration "
173 "as dllimport: attribute ignored", decl, decl);
174 return 0;
177 /* We ignore the dllimport attribute for inline member functions.
178 This differs from MSVC behavior which treats it like GNUC
179 'extern inline' extension. */
180 else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
182 if (extra_warnings)
183 warning ("%Jinline function '%D' is declared as dllimport: "
184 "attribute ignored.", decl, decl);
185 return 0;
188 /* Don't allow definitions of static data members in dllimport class,
189 Just ignore attribute for vtable data. */
190 else if (TREE_CODE (decl) == VAR_DECL
191 && TREE_STATIC (decl) && TREE_PUBLIC (decl)
192 && !DECL_EXTERNAL (decl) && context_imp)
194 if (!DECL_VIRTUAL_P (decl))
195 error ("%Jdefinition of static data member '%D' of "
196 "dllimport'd class.", decl, decl);
197 return 0;
200 /* Since we can't treat a pointer to a dllimport'd symbol as a
201 constant address, we turn off the attribute on C++ virtual
202 methods to allow creation of vtables using thunks. Don't mark
203 artificial methods either (in associated_type, only COMDAT
204 artificial method get import status from class context). */
205 else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
206 && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
207 return 0;
209 return 1;
212 return 0;
215 /* Return nonzero if SYMBOL is marked as being dllexport'd. */
218 i386_pe_dllexport_name_p (const char *symbol)
220 return (strncmp (DLL_EXPORT_PREFIX, symbol,
221 strlen (DLL_EXPORT_PREFIX)) == 0);
224 /* Return nonzero if SYMBOL is marked as being dllimport'd. */
227 i386_pe_dllimport_name_p (const char *symbol)
229 return (strncmp (DLL_IMPORT_PREFIX, symbol,
230 strlen (DLL_IMPORT_PREFIX)) == 0);
233 /* Mark a DECL as being dllexport'd.
234 Note that we override the previous setting (e.g.: dllimport). */
236 static void
237 i386_pe_mark_dllexport (tree decl)
239 const char *oldname;
240 char *newname;
241 rtx rtlname;
242 rtx symref;
243 tree idp;
245 rtlname = XEXP (DECL_RTL (decl), 0);
246 if (GET_CODE (rtlname) == SYMBOL_REF)
247 oldname = XSTR (rtlname, 0);
248 else if (GET_CODE (rtlname) == MEM
249 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
250 oldname = XSTR (XEXP (rtlname, 0), 0);
251 else
252 abort ();
253 if (i386_pe_dllimport_name_p (oldname))
255 warning ("%Jinconsistent dll linkage for '%D', dllexport assumed.",
256 decl, decl);
257 /* Remove DLL_IMPORT_PREFIX. */
258 oldname += strlen (DLL_IMPORT_PREFIX);
259 DECL_NON_ADDR_CONST_P (decl) = 0;
261 else if (i386_pe_dllexport_name_p (oldname))
262 return; /* already done */
264 newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
265 sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
267 /* We pass newname through get_identifier to ensure it has a unique
268 address. RTL processing can sometimes peek inside the symbol ref
269 and compare the string's addresses to see if two symbols are
270 identical. */
271 idp = get_identifier (newname);
273 symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
274 SYMBOL_REF_DECL (symref) = decl;
275 XEXP (DECL_RTL (decl), 0) = symref;
278 /* Mark a DECL as being dllimport'd. */
280 static void
281 i386_pe_mark_dllimport (tree decl)
283 const char *oldname;
284 char *newname;
285 tree idp;
286 rtx rtlname, newrtl;
287 rtx symref;
289 rtlname = XEXP (DECL_RTL (decl), 0);
290 if (GET_CODE (rtlname) == SYMBOL_REF)
291 oldname = XSTR (rtlname, 0);
292 else if (GET_CODE (rtlname) == MEM
293 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
294 oldname = XSTR (XEXP (rtlname, 0), 0);
295 else
296 abort ();
297 if (i386_pe_dllexport_name_p (oldname))
299 error ("`%s' declared as both exported to and imported from a DLL",
300 IDENTIFIER_POINTER (DECL_NAME (decl)));
301 return;
303 else if (i386_pe_dllimport_name_p (oldname))
305 /* Already done, but do a sanity check to prevent assembler errors. */
306 if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
308 error ("%Jfailure in redeclaration of '%D': dllimport'd "
309 "symbol lacks external linkage.", decl, decl);
310 abort();
312 return;
315 newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
316 sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
318 /* We pass newname through get_identifier to ensure it has a unique
319 address. RTL processing can sometimes peek inside the symbol ref
320 and compare the string's addresses to see if two symbols are
321 identical. */
322 idp = get_identifier (newname);
324 symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
325 SYMBOL_REF_DECL (symref) = decl;
326 newrtl = gen_rtx_MEM (Pmode,symref);
327 XEXP (DECL_RTL (decl), 0) = newrtl;
329 /* Can't treat a pointer to this as a constant address */
330 DECL_NON_ADDR_CONST_P (decl) = 1;
333 /* Return string which is the former assembler name modified with a
334 suffix consisting of an atsign (@) followed by the number of bytes of
335 arguments. If FASTCALL is true, also add the FASTCALL_PREFIX. */
337 static tree
338 gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
340 int total = 0;
341 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
342 of DECL_ASSEMBLER_NAME. */
343 const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
344 char *newsym;
345 char *p;
346 tree formal_type;
348 /* Do not change the identifier if a verbatim asmspec or already done. */
349 if (*asmname == '*' || strchr (asmname, '@'))
350 return DECL_ASSEMBLER_NAME (decl);
352 formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
353 if (formal_type != NULL_TREE)
355 /* These attributes are ignored for variadic functions in
356 i386.c:ix86_return_pops_args. For compatibility with MS
357 compiler do not add @0 suffix here. */
358 if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
359 return DECL_ASSEMBLER_NAME (decl);
361 /* Quit if we hit an incomplete type. Error is reported
362 by convert_arguments in c-typeck.c or cp/typeck.c. */
363 while (TREE_VALUE (formal_type) != void_type_node
364 && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
366 int parm_size
367 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
368 /* Must round up to include padding. This is done the same
369 way as in store_one_arg. */
370 parm_size = ((parm_size + PARM_BOUNDARY - 1)
371 / PARM_BOUNDARY * PARM_BOUNDARY);
372 total += parm_size;
373 formal_type = TREE_CHAIN (formal_type);\
377 /* Assume max of 8 base 10 digits in the suffix. */
378 newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
379 p = newsym;
380 if (fastcall)
381 *p++ = FASTCALL_PREFIX;
382 sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
383 return get_identifier (newsym);
386 void
387 i386_pe_encode_section_info (tree decl, rtx rtl, int first)
389 default_encode_section_info (decl, rtl, first);
391 if (first && TREE_CODE (decl) == FUNCTION_DECL)
393 tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
394 tree newid = NULL_TREE;
396 if (lookup_attribute ("stdcall", type_attributes))
397 newid = gen_stdcall_or_fastcall_suffix (decl, false);
398 else if (lookup_attribute ("fastcall", type_attributes))
399 newid = gen_stdcall_or_fastcall_suffix (decl, true);
400 if (newid != NULL_TREE)
402 rtx rtlname = XEXP (rtl, 0);
403 if (GET_CODE (rtlname) == MEM)
404 rtlname = XEXP (rtlname, 0);
405 XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
406 /* These attributes must be present on first declaration,
407 change_decl_assembler_name will warn if they are added
408 later and the decl has been referenced, but duplicate_decls
409 should catch the mismatch before this is called. */
410 change_decl_assembler_name (decl, newid);
414 /* Mark the decl so we can tell from the rtl whether the object is
415 dllexport'd or dllimport'd. This also handles dllexport/dllimport
416 override semantics. */
418 if (i386_pe_dllexport_p (decl))
419 i386_pe_mark_dllexport (decl);
420 else if (i386_pe_dllimport_p (decl))
421 i386_pe_mark_dllimport (decl);
422 /* It might be that DECL has already been marked as dllimport, but a
423 subsequent definition nullified that. The attribute is gone but
424 DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
425 that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
426 else if ((TREE_CODE (decl) == FUNCTION_DECL
427 || TREE_CODE (decl) == VAR_DECL)
428 && DECL_RTL (decl) != NULL_RTX
429 && GET_CODE (DECL_RTL (decl)) == MEM
430 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
431 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
432 && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
434 const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
436 /* Remove DLL_IMPORT_PREFIX. */
437 tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
438 rtx symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
439 SYMBOL_REF_DECL (symref) = decl;
440 XEXP (DECL_RTL (decl), 0) = symref;
441 DECL_NON_ADDR_CONST_P (decl) = 0;
443 /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
444 We leave these alone for now. */
446 if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
447 warning ("%J'%D' defined locally after being "
448 "referenced with dllimport linkage", decl, decl);
449 else
450 warning ("%J'%D' redeclared without dllimport attribute "
451 "after being referenced with dllimport linkage", decl, decl);
455 /* Strip only the leading encoding, leaving the stdcall suffix and fastcall
456 prefix if it exists. */
458 const char *
459 i386_pe_strip_name_encoding (const char *str)
461 if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
462 == 0)
463 str += strlen (DLL_IMPORT_PREFIX);
464 else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
465 == 0)
466 str += strlen (DLL_EXPORT_PREFIX);
467 if (*str == '*')
468 str += 1;
469 return str;
472 /* Also strip the fastcall prefix and stdcall suffix. */
474 const char *
475 i386_pe_strip_name_encoding_full (const char *str)
477 const char *p;
478 const char *name = i386_pe_strip_name_encoding (str);
480 /* Strip leading '@' on fastcall symbols. */
481 if (*name == '@')
482 name++;
484 /* Strip trailing "@n". */
485 p = strchr (name, '@');
486 if (p)
487 return ggc_alloc_string (name, p - name);
489 return name;
492 /* Output a reference to a label. Fastcall symbols are prefixed with @,
493 whereas symbols for functions using other calling conventions don't
494 have a prefix (unless they are marked dllimport or dllexport). */
496 void i386_pe_output_labelref (FILE *stream, const char *name)
498 if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
499 == 0)
500 /* A dll import */
502 if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
503 /* A dllimport fastcall symbol. */
505 fprintf (stream, "__imp_%s",
506 i386_pe_strip_name_encoding (name));
508 else
509 /* A dllimport non-fastcall symbol. */
511 fprintf (stream, "__imp__%s",
512 i386_pe_strip_name_encoding (name));
515 else if ((name[0] == FASTCALL_PREFIX)
516 || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
517 == 0
518 && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX))
519 /* A fastcall symbol. */
521 fprintf (stream, "%s",
522 i386_pe_strip_name_encoding (name));
524 else
525 /* Everything else. */
527 fprintf (stream, "%s%s", USER_LABEL_PREFIX,
528 i386_pe_strip_name_encoding (name));
532 void
533 i386_pe_unique_section (tree decl, int reloc)
535 int len;
536 const char *name, *prefix;
537 char *string;
539 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
540 name = i386_pe_strip_name_encoding_full (name);
542 /* The object is put in, for example, section .text$foo.
543 The linker will then ultimately place them in .text
544 (everything from the $ on is stripped). Don't put
545 read-only data in .rdata section to avoid a PE linker
546 bug when .rdata$* grouped sections are used in code
547 without a .rdata section. */
548 if (TREE_CODE (decl) == FUNCTION_DECL)
549 prefix = ".text$";
550 else if (decl_readonly_section (decl, reloc))
551 prefix = ".rdata$";
552 else
553 prefix = ".data$";
554 len = strlen (name) + strlen (prefix);
555 string = alloca (len + 1);
556 sprintf (string, "%s%s", prefix, name);
558 DECL_SECTION_NAME (decl) = build_string (len, string);
561 /* Select a set of attributes for section NAME based on the properties
562 of DECL and whether or not RELOC indicates that DECL's initializer
563 might contain runtime relocations.
565 We make the section read-only and executable for a function decl,
566 read-only for a const data decl, and writable for a non-const data decl.
568 If the section has already been defined, to not allow it to have
569 different attributes, as (1) this is ambiguous since we're not seeing
570 all the declarations up front and (2) some assemblers (e.g. SVR4)
571 do not recognize section redefinitions. */
572 /* ??? This differs from the "standard" PE implementation in that we
573 handle the SHARED variable attribute. Should this be done for all
574 PE targets? */
576 #define SECTION_PE_SHARED SECTION_MACH_DEP
578 unsigned int
579 i386_pe_section_type_flags (tree decl, const char *name, int reloc)
581 static htab_t htab;
582 unsigned int flags;
583 unsigned int **slot;
585 /* The names we put in the hashtable will always be the unique
586 versions given to us by the stringtable, so we can just use
587 their addresses as the keys. */
588 if (!htab)
589 htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
591 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
592 flags = SECTION_CODE;
593 else if (decl && decl_readonly_section (decl, reloc))
594 flags = 0;
595 else
597 flags = SECTION_WRITE;
599 if (decl && TREE_CODE (decl) == VAR_DECL
600 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
601 flags |= SECTION_PE_SHARED;
604 if (decl && DECL_ONE_ONLY (decl))
605 flags |= SECTION_LINKONCE;
607 /* See if we already have an entry for this section. */
608 slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
609 if (!*slot)
611 *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
612 **slot = flags;
614 else
616 if (decl && **slot != flags)
617 error ("%J'%D' causes a section type conflict", decl, decl);
620 return flags;
623 void
624 i386_pe_asm_named_section (const char *name, unsigned int flags,
625 tree decl ATTRIBUTE_UNUSED)
627 char flagchars[8], *f = flagchars;
629 if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
630 /* readonly data */
632 *f++ ='d'; /* This is necessary for older versions of gas. */
633 *f++ ='r';
635 else
637 if (flags & SECTION_CODE)
638 *f++ = 'x';
639 if (flags & SECTION_WRITE)
640 *f++ = 'w';
641 if (flags & SECTION_PE_SHARED)
642 *f++ = 's';
645 *f = '\0';
647 fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
649 if (flags & SECTION_LINKONCE)
651 /* Functions may have been compiled at various levels of
652 optimization so we can't use `same_size' here.
653 Instead, have the linker pick one. */
654 fprintf (asm_out_file, "\t.linkonce %s\n",
655 (flags & SECTION_CODE ? "discard" : "same_size"));
659 /* The Microsoft linker requires that every function be marked as
660 DT_FCN. When using gas on cygwin, we must emit appropriate .type
661 directives. */
663 #include "gsyms.h"
665 /* Mark a function appropriately. This should only be called for
666 functions for which we are not emitting COFF debugging information.
667 FILE is the assembler output file, NAME is the name of the
668 function, and PUBLIC is nonzero if the function is globally
669 visible. */
671 void
672 i386_pe_declare_function_type (FILE *file, const char *name, int public)
674 fprintf (file, "\t.def\t");
675 assemble_name (file, name);
676 fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
677 public ? (int) C_EXT : (int) C_STAT,
678 (int) DT_FCN << N_BTSHFT);
681 /* Keep a list of external functions. */
683 struct extern_list GTY(())
685 struct extern_list *next;
686 const char *name;
689 static GTY(()) struct extern_list *extern_head;
691 /* Assemble an external function reference. We need to keep a list of
692 these, so that we can output the function types at the end of the
693 assembly. We can't output the types now, because we might see a
694 definition of the function later on and emit debugging information
695 for it then. */
697 void
698 i386_pe_record_external_function (const char *name)
700 struct extern_list *p;
702 p = (struct extern_list *) ggc_alloc (sizeof *p);
703 p->next = extern_head;
704 p->name = name;
705 extern_head = p;
708 /* Keep a list of exported symbols. */
710 struct export_list GTY(())
712 struct export_list *next;
713 const char *name;
714 int is_data; /* used to type tag exported symbols. */
717 static GTY(()) struct export_list *export_head;
719 /* Assemble an export symbol entry. We need to keep a list of
720 these, so that we can output the export list at the end of the
721 assembly. We used to output these export symbols in each function,
722 but that causes problems with GNU ld when the sections are
723 linkonce. */
725 void
726 i386_pe_record_exported_symbol (const char *name, int is_data)
728 struct export_list *p;
730 p = (struct export_list *) ggc_alloc (sizeof *p);
731 p->next = export_head;
732 p->name = name;
733 p->is_data = is_data;
734 export_head = p;
737 /* This is called at the end of assembly. For each external function
738 which has not been defined, we output a declaration now. We also
739 output the .drectve section. */
741 void
742 i386_pe_file_end (void)
744 struct extern_list *p;
746 ix86_file_end ();
748 for (p = extern_head; p != NULL; p = p->next)
750 tree decl;
752 decl = get_identifier (p->name);
754 /* Positively ensure only one declaration for any given symbol. */
755 if (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl))
757 TREE_ASM_WRITTEN (decl) = 1;
758 i386_pe_declare_function_type (asm_out_file, p->name,
759 TREE_PUBLIC (decl));
763 if (export_head)
765 struct export_list *q;
766 drectve_section ();
767 for (q = export_head; q != NULL; q = q->next)
769 fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
770 i386_pe_strip_name_encoding (q->name),
771 (q->is_data) ? ",data" : "");
776 #include "gt-winnt.h"