* common.opt (-Wattributes): New. Default true.
[official-gcc.git] / gcc / config / i386 / winnt.c
blob6eae2e74efad27c28795e5540baed8c019e8620c
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, 2005
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 (OPT_Wattributes, "%qs attribute only applies to variables",
75 IDENTIFIER_POINTER (name));
76 *no_add_attrs = true;
79 return NULL_TREE;
82 /* Handle a "selectany" attribute;
83 arguments as in struct attribute_spec.handler. */
84 tree
85 ix86_handle_selectany_attribute (tree *node, tree name,
86 tree args ATTRIBUTE_UNUSED,
87 int flags ATTRIBUTE_UNUSED,
88 bool *no_add_attrs)
90 /* The attribute applies only to objects that are initialized and have
91 external linkage, */
92 if (TREE_CODE (*node) == VAR_DECL && TREE_PUBLIC (*node)
93 && (DECL_INITIAL (*node)
94 /* If an object is initialized with a ctor, the static
95 initialization and destruction code for it is present in
96 each unit defining the object. The code that calls the
97 ctor is protected by a link-once guard variable, so that
98 the object still has link-once semantics, */
99 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (*node))))
100 make_decl_one_only (*node);
101 else
103 error ("%qs attribute applies only to initialized variables"
104 " with external linkage", IDENTIFIER_POINTER (name));
105 *no_add_attrs = true;
108 return NULL_TREE;
112 /* Return the type that we should use to determine if DECL is
113 imported or exported. */
115 static tree
116 associated_type (tree decl)
118 tree t = NULL_TREE;
120 /* In the C++ frontend, DECL_CONTEXT for a method doesn't actually refer
121 to the containing class. So we look at the 'this' arg. */
122 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
124 /* Artificial methods are not affected by the import/export status
125 of their class unless they are COMDAT. Implicit copy ctor's and
126 dtor's are not affected by class status but virtual and
127 non-virtual thunks are. */
128 if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl))
129 t = TYPE_MAIN_VARIANT
130 (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
132 else if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
133 t = DECL_CONTEXT (decl);
135 return t;
138 /* Return nonzero if DECL is a dllexport'd object. */
140 static int
141 i386_pe_dllexport_p (tree decl)
143 tree exp;
145 if (TREE_CODE (decl) != VAR_DECL
146 && TREE_CODE (decl) != FUNCTION_DECL)
147 return 0;
148 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
149 if (exp)
150 return 1;
152 /* Class members get the dllexport status of their class. */
153 if (associated_type (decl))
155 exp = lookup_attribute ("dllexport",
156 TYPE_ATTRIBUTES (associated_type (decl)));
157 if (exp)
158 return 1;
161 return 0;
164 /* Return nonzero if DECL is a dllimport'd object. */
166 static int
167 i386_pe_dllimport_p (tree decl)
169 tree imp;
170 int context_imp = 0;
172 if (TREE_CODE (decl) == FUNCTION_DECL
173 && TARGET_NOP_FUN_DLLIMPORT)
174 return 0;
176 if (TREE_CODE (decl) != VAR_DECL
177 && TREE_CODE (decl) != FUNCTION_DECL)
178 return 0;
180 imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
182 /* Class members get the dllimport status of their class. */
183 if (!imp && associated_type (decl))
185 imp = lookup_attribute ("dllimport",
186 TYPE_ATTRIBUTES (associated_type (decl)));
187 if (imp)
188 context_imp = 1;
191 if (imp)
193 /* Don't mark defined functions as dllimport. If the definition
194 itself was marked with dllimport, than ix86_handle_dll_attribute
195 reports an error. This handles the case when the definition
196 overrides an earlier declaration. */
197 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)
198 && !DECL_INLINE (decl))
200 /* Don't warn about artificial methods. */
201 if (!DECL_ARTIFICIAL (decl))
202 warning (0, "%Jfunction '%D' is defined after prior declaration "
203 "as dllimport: attribute ignored", decl, decl);
204 return 0;
207 /* We ignore the dllimport attribute for inline member functions.
208 This differs from MSVC behavior which treats it like GNUC
209 'extern inline' extension. */
210 else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
212 if (extra_warnings)
213 warning (0, "%Jinline function '%D' is declared as dllimport: "
214 "attribute ignored.", decl, decl);
215 return 0;
218 /* Don't allow definitions of static data members in dllimport class,
219 Just ignore attribute for vtable data. */
220 else if (TREE_CODE (decl) == VAR_DECL
221 && TREE_STATIC (decl) && TREE_PUBLIC (decl)
222 && !DECL_EXTERNAL (decl) && context_imp)
224 if (!DECL_VIRTUAL_P (decl))
225 error ("%Jdefinition of static data member '%D' of "
226 "dllimport'd class.", decl, decl);
227 return 0;
230 /* Since we can't treat a pointer to a dllimport'd symbol as a
231 constant address, we turn off the attribute on C++ virtual
232 methods to allow creation of vtables using thunks. Don't mark
233 artificial methods either (in associated_type, only COMDAT
234 artificial method get import status from class context). */
235 else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
236 && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
237 return 0;
239 return 1;
242 return 0;
245 /* Return nonzero if SYMBOL is marked as being dllexport'd. */
248 i386_pe_dllexport_name_p (const char *symbol)
250 return (strncmp (DLL_EXPORT_PREFIX, symbol,
251 strlen (DLL_EXPORT_PREFIX)) == 0);
254 /* Return nonzero if SYMBOL is marked as being dllimport'd. */
257 i386_pe_dllimport_name_p (const char *symbol)
259 return (strncmp (DLL_IMPORT_PREFIX, symbol,
260 strlen (DLL_IMPORT_PREFIX)) == 0);
263 /* Mark a DECL as being dllexport'd.
264 Note that we override the previous setting (e.g.: dllimport). */
266 static void
267 i386_pe_mark_dllexport (tree decl)
269 const char *oldname;
270 char *newname;
271 rtx rtlname;
272 rtx symref;
273 tree idp;
275 rtlname = XEXP (DECL_RTL (decl), 0);
276 if (GET_CODE (rtlname) == MEM)
277 rtlname = XEXP (rtlname, 0);
278 gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
279 oldname = XSTR (rtlname, 0);
280 if (i386_pe_dllimport_name_p (oldname))
282 warning (0, "%Jinconsistent dll linkage for '%D', dllexport assumed.",
283 decl, decl);
284 /* Remove DLL_IMPORT_PREFIX. */
285 oldname += strlen (DLL_IMPORT_PREFIX);
286 DECL_NON_ADDR_CONST_P (decl) = 0;
288 else if (i386_pe_dllexport_name_p (oldname))
289 return; /* already done */
291 newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
292 sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
294 /* We pass newname through get_identifier to ensure it has a unique
295 address. RTL processing can sometimes peek inside the symbol ref
296 and compare the string's addresses to see if two symbols are
297 identical. */
298 idp = get_identifier (newname);
300 symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
301 SYMBOL_REF_DECL (symref) = decl;
302 XEXP (DECL_RTL (decl), 0) = symref;
305 /* Mark a DECL as being dllimport'd. */
307 static void
308 i386_pe_mark_dllimport (tree decl)
310 const char *oldname;
311 char *newname;
312 tree idp;
313 rtx rtlname, newrtl;
314 rtx symref;
316 rtlname = XEXP (DECL_RTL (decl), 0);
317 if (GET_CODE (rtlname) == MEM)
318 rtlname = XEXP (rtlname, 0);
319 gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
320 oldname = XSTR (rtlname, 0);
321 if (i386_pe_dllexport_name_p (oldname))
323 error ("%qs declared as both exported to and imported from a DLL",
324 IDENTIFIER_POINTER (DECL_NAME (decl)));
325 return;
327 else if (i386_pe_dllimport_name_p (oldname))
329 /* Already done, but do a sanity check to prevent assembler
330 errors. */
331 gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl));
334 newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
335 sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
337 /* We pass newname through get_identifier to ensure it has a unique
338 address. RTL processing can sometimes peek inside the symbol ref
339 and compare the string's addresses to see if two symbols are
340 identical. */
341 idp = get_identifier (newname);
343 symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
344 SYMBOL_REF_DECL (symref) = decl;
345 newrtl = gen_rtx_MEM (Pmode,symref);
346 XEXP (DECL_RTL (decl), 0) = newrtl;
348 /* Can't treat a pointer to this as a constant address */
349 DECL_NON_ADDR_CONST_P (decl) = 1;
352 /* Return string which is the former assembler name modified with a
353 suffix consisting of an atsign (@) followed by the number of bytes of
354 arguments. If FASTCALL is true, also add the FASTCALL_PREFIX. */
356 static tree
357 gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
359 int total = 0;
360 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
361 of DECL_ASSEMBLER_NAME. */
362 const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
363 char *newsym;
364 char *p;
365 tree formal_type;
367 /* Do not change the identifier if a verbatim asmspec or already done. */
368 if (*asmname == '*' || strchr (asmname, '@'))
369 return DECL_ASSEMBLER_NAME (decl);
371 formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
372 if (formal_type != NULL_TREE)
374 /* These attributes are ignored for variadic functions in
375 i386.c:ix86_return_pops_args. For compatibility with MS
376 compiler do not add @0 suffix here. */
377 if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
378 return DECL_ASSEMBLER_NAME (decl);
380 /* Quit if we hit an incomplete type. Error is reported
381 by convert_arguments in c-typeck.c or cp/typeck.c. */
382 while (TREE_VALUE (formal_type) != void_type_node
383 && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
385 int parm_size
386 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
387 /* Must round up to include padding. This is done the same
388 way as in store_one_arg. */
389 parm_size = ((parm_size + PARM_BOUNDARY - 1)
390 / PARM_BOUNDARY * PARM_BOUNDARY);
391 total += parm_size;
392 formal_type = TREE_CHAIN (formal_type);\
396 /* Assume max of 8 base 10 digits in the suffix. */
397 newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
398 p = newsym;
399 if (fastcall)
400 *p++ = FASTCALL_PREFIX;
401 sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
402 return get_identifier (newsym);
405 void
406 i386_pe_encode_section_info (tree decl, rtx rtl, int first)
408 default_encode_section_info (decl, rtl, first);
410 if (first && TREE_CODE (decl) == FUNCTION_DECL)
412 tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
413 tree newid = NULL_TREE;
415 if (lookup_attribute ("stdcall", type_attributes))
416 newid = gen_stdcall_or_fastcall_suffix (decl, false);
417 else if (lookup_attribute ("fastcall", type_attributes))
418 newid = gen_stdcall_or_fastcall_suffix (decl, true);
419 if (newid != NULL_TREE)
421 rtx rtlname = XEXP (rtl, 0);
422 if (GET_CODE (rtlname) == MEM)
423 rtlname = XEXP (rtlname, 0);
424 XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
425 /* These attributes must be present on first declaration,
426 change_decl_assembler_name will warn if they are added
427 later and the decl has been referenced, but duplicate_decls
428 should catch the mismatch before this is called. */
429 change_decl_assembler_name (decl, newid);
433 /* Mark the decl so we can tell from the rtl whether the object is
434 dllexport'd or dllimport'd. This also handles dllexport/dllimport
435 override semantics. */
437 if (i386_pe_dllexport_p (decl))
438 i386_pe_mark_dllexport (decl);
439 else if (i386_pe_dllimport_p (decl))
440 i386_pe_mark_dllimport (decl);
441 /* It might be that DECL has already been marked as dllimport, but a
442 subsequent definition nullified that. The attribute is gone but
443 DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
444 that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
445 else if ((TREE_CODE (decl) == FUNCTION_DECL
446 || TREE_CODE (decl) == VAR_DECL)
447 && DECL_RTL (decl) != NULL_RTX
448 && GET_CODE (DECL_RTL (decl)) == MEM
449 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
450 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
451 && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
453 const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
455 /* Remove DLL_IMPORT_PREFIX. */
456 tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
457 rtx symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
458 SYMBOL_REF_DECL (symref) = decl;
459 XEXP (DECL_RTL (decl), 0) = symref;
460 DECL_NON_ADDR_CONST_P (decl) = 0;
462 /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
463 We leave these alone for now. */
465 if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
466 warning (0, "%J'%D' defined locally after being "
467 "referenced with dllimport linkage", decl, decl);
468 else
469 warning (OPT_Wattributes, "%J'%D' redeclared without dllimport "
470 "attribute after being referenced with dllimport linkage",
471 decl, decl);
475 /* Strip only the leading encoding, leaving the stdcall suffix and fastcall
476 prefix if it exists. */
478 const char *
479 i386_pe_strip_name_encoding (const char *str)
481 if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
482 == 0)
483 str += strlen (DLL_IMPORT_PREFIX);
484 else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
485 == 0)
486 str += strlen (DLL_EXPORT_PREFIX);
487 if (*str == '*')
488 str += 1;
489 return str;
492 /* Also strip the fastcall prefix and stdcall suffix. */
494 const char *
495 i386_pe_strip_name_encoding_full (const char *str)
497 const char *p;
498 const char *name = i386_pe_strip_name_encoding (str);
500 /* Strip leading '@' on fastcall symbols. */
501 if (*name == '@')
502 name++;
504 /* Strip trailing "@n". */
505 p = strchr (name, '@');
506 if (p)
507 return ggc_alloc_string (name, p - name);
509 return name;
512 /* Output a reference to a label. Fastcall symbols are prefixed with @,
513 whereas symbols for functions using other calling conventions don't
514 have a prefix (unless they are marked dllimport or dllexport). */
516 void i386_pe_output_labelref (FILE *stream, const char *name)
518 if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
519 == 0)
520 /* A dll import */
522 if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
523 /* A dllimport fastcall symbol. */
525 fprintf (stream, "__imp_%s",
526 i386_pe_strip_name_encoding (name));
528 else
529 /* A dllimport non-fastcall symbol. */
531 fprintf (stream, "__imp__%s",
532 i386_pe_strip_name_encoding (name));
535 else if ((name[0] == FASTCALL_PREFIX)
536 || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
537 == 0
538 && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX))
539 /* A fastcall symbol. */
541 fprintf (stream, "%s",
542 i386_pe_strip_name_encoding (name));
544 else
545 /* Everything else. */
547 fprintf (stream, "%s%s", USER_LABEL_PREFIX,
548 i386_pe_strip_name_encoding (name));
552 void
553 i386_pe_unique_section (tree decl, int reloc)
555 int len;
556 const char *name, *prefix;
557 char *string;
559 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
560 name = i386_pe_strip_name_encoding_full (name);
562 /* The object is put in, for example, section .text$foo.
563 The linker will then ultimately place them in .text
564 (everything from the $ on is stripped). Don't put
565 read-only data in .rdata section to avoid a PE linker
566 bug when .rdata$* grouped sections are used in code
567 without a .rdata section. */
568 if (TREE_CODE (decl) == FUNCTION_DECL)
569 prefix = ".text$";
570 else if (decl_readonly_section (decl, reloc))
571 prefix = ".rdata$";
572 else
573 prefix = ".data$";
574 len = strlen (name) + strlen (prefix);
575 string = alloca (len + 1);
576 sprintf (string, "%s%s", prefix, name);
578 DECL_SECTION_NAME (decl) = build_string (len, string);
581 /* Select a set of attributes for section NAME based on the properties
582 of DECL and whether or not RELOC indicates that DECL's initializer
583 might contain runtime relocations.
585 We make the section read-only and executable for a function decl,
586 read-only for a const data decl, and writable for a non-const data decl.
588 If the section has already been defined, to not allow it to have
589 different attributes, as (1) this is ambiguous since we're not seeing
590 all the declarations up front and (2) some assemblers (e.g. SVR4)
591 do not recognize section redefinitions. */
592 /* ??? This differs from the "standard" PE implementation in that we
593 handle the SHARED variable attribute. Should this be done for all
594 PE targets? */
596 #define SECTION_PE_SHARED SECTION_MACH_DEP
598 unsigned int
599 i386_pe_section_type_flags (tree decl, const char *name, int reloc)
601 static htab_t htab;
602 unsigned int flags;
603 unsigned int **slot;
605 /* The names we put in the hashtable will always be the unique
606 versions given to us by the stringtable, so we can just use
607 their addresses as the keys. */
608 if (!htab)
609 htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
611 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
612 flags = SECTION_CODE;
613 else if (decl && decl_readonly_section (decl, reloc))
614 flags = 0;
615 else
617 flags = SECTION_WRITE;
619 if (decl && TREE_CODE (decl) == VAR_DECL
620 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
621 flags |= SECTION_PE_SHARED;
624 if (decl && DECL_ONE_ONLY (decl))
625 flags |= SECTION_LINKONCE;
627 /* See if we already have an entry for this section. */
628 slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
629 if (!*slot)
631 *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
632 **slot = flags;
634 else
636 if (decl && **slot != flags)
637 error ("%J'%D' causes a section type conflict", decl, decl);
640 return flags;
643 void
644 i386_pe_asm_named_section (const char *name, unsigned int flags,
645 tree decl)
647 char flagchars[8], *f = flagchars;
649 if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
650 /* readonly data */
652 *f++ ='d'; /* This is necessary for older versions of gas. */
653 *f++ ='r';
655 else
657 if (flags & SECTION_CODE)
658 *f++ = 'x';
659 if (flags & SECTION_WRITE)
660 *f++ = 'w';
661 if (flags & SECTION_PE_SHARED)
662 *f++ = 's';
665 *f = '\0';
667 fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
669 if (flags & SECTION_LINKONCE)
671 /* Functions may have been compiled at various levels of
672 optimization so we can't use `same_size' here.
673 Instead, have the linker pick one, without warning.
674 If 'selectany' attribute has been specified, MS compiler
675 sets 'discard' characteristic, rather than telling linker
676 to warn of size or content mismatch, so do the same. */
677 bool discard = (flags & SECTION_CODE)
678 || lookup_attribute ("selectany",
679 DECL_ATTRIBUTES (decl));
680 fprintf (asm_out_file, "\t.linkonce %s\n",
681 (discard ? "discard" : "same_size"));
685 /* The Microsoft linker requires that every function be marked as
686 DT_FCN. When using gas on cygwin, we must emit appropriate .type
687 directives. */
689 #include "gsyms.h"
691 /* Mark a function appropriately. This should only be called for
692 functions for which we are not emitting COFF debugging information.
693 FILE is the assembler output file, NAME is the name of the
694 function, and PUBLIC is nonzero if the function is globally
695 visible. */
697 void
698 i386_pe_declare_function_type (FILE *file, const char *name, int public)
700 fprintf (file, "\t.def\t");
701 assemble_name (file, name);
702 fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
703 public ? (int) C_EXT : (int) C_STAT,
704 (int) DT_FCN << N_BTSHFT);
707 /* Keep a list of external functions. */
709 struct extern_list GTY(())
711 struct extern_list *next;
712 tree decl;
713 const char *name;
716 static GTY(()) struct extern_list *extern_head;
718 /* Assemble an external function reference. We need to keep a list of
719 these, so that we can output the function types at the end of the
720 assembly. We can't output the types now, because we might see a
721 definition of the function later on and emit debugging information
722 for it then. */
724 void
725 i386_pe_record_external_function (tree decl, const char *name)
727 struct extern_list *p;
729 p = (struct extern_list *) ggc_alloc (sizeof *p);
730 p->next = extern_head;
731 p->decl = decl;
732 p->name = name;
733 extern_head = p;
736 /* Keep a list of exported symbols. */
738 struct export_list GTY(())
740 struct export_list *next;
741 const char *name;
742 int is_data; /* used to type tag exported symbols. */
745 static GTY(()) struct export_list *export_head;
747 /* Assemble an export symbol entry. We need to keep a list of
748 these, so that we can output the export list at the end of the
749 assembly. We used to output these export symbols in each function,
750 but that causes problems with GNU ld when the sections are
751 linkonce. */
753 void
754 i386_pe_record_exported_symbol (const char *name, int is_data)
756 struct export_list *p;
758 p = (struct export_list *) ggc_alloc (sizeof *p);
759 p->next = export_head;
760 p->name = name;
761 p->is_data = is_data;
762 export_head = p;
765 /* This is called at the end of assembly. For each external function
766 which has not been defined, we output a declaration now. We also
767 output the .drectve section. */
769 void
770 i386_pe_file_end (void)
772 struct extern_list *p;
774 ix86_file_end ();
776 for (p = extern_head; p != NULL; p = p->next)
778 tree decl;
780 decl = p->decl;
782 /* Positively ensure only one declaration for any given symbol. */
783 if (! TREE_ASM_WRITTEN (decl)
784 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
786 TREE_ASM_WRITTEN (decl) = 1;
787 i386_pe_declare_function_type (asm_out_file, p->name,
788 TREE_PUBLIC (decl));
792 if (export_head)
794 struct export_list *q;
795 drectve_section ();
796 for (q = export_head; q != NULL; q = q->next)
798 fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
799 i386_pe_strip_name_encoding (q->name),
800 (q->is_data) ? ",data" : "");
805 #include "gt-winnt.h"