Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/i386/winnt.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Subroutines for insn-output.c for Windows NT. | 1 /* Subroutines for insn-output.c for Windows NT. |
2 Contributed by Douglas Rupp (drupp@cs.washington.edu) | 2 Contributed by Douglas Rupp (drupp@cs.washington.edu) |
3 Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
4 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | 4 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 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 | 9 the terms of the GNU General Public License as published by the Free |
54 tree args ATTRIBUTE_UNUSED, | 54 tree args ATTRIBUTE_UNUSED, |
55 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) | 55 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) |
56 { | 56 { |
57 if (TREE_CODE (*node) != VAR_DECL) | 57 if (TREE_CODE (*node) != VAR_DECL) |
58 { | 58 { |
59 warning (OPT_Wattributes, "%qs attribute only applies to variables", | 59 warning (OPT_Wattributes, "%qE attribute only applies to variables", |
60 IDENTIFIER_POINTER (name)); | 60 name); |
61 *no_add_attrs = true; | 61 *no_add_attrs = true; |
62 } | 62 } |
63 | 63 |
64 return NULL_TREE; | 64 return NULL_TREE; |
65 } | 65 } |
76 external linkage. However, we may not know about initialization | 76 external linkage. However, we may not know about initialization |
77 until the language frontend has processed the decl. We'll check for | 77 until the language frontend has processed the decl. We'll check for |
78 initialization later in encode_section_info. */ | 78 initialization later in encode_section_info. */ |
79 if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node)) | 79 if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node)) |
80 { | 80 { |
81 error ("%qs attribute applies only to initialized variables" | 81 error ("%qE attribute applies only to initialized variables" |
82 " with external linkage", IDENTIFIER_POINTER (name)); | 82 " with external linkage", name); |
83 *no_add_attrs = true; | 83 *no_add_attrs = true; |
84 } | 84 } |
85 | 85 |
86 return NULL_TREE; | 86 return NULL_TREE; |
87 } | 87 } |
100 /* Return true if DECL should be a dllexport'd object. */ | 100 /* Return true if DECL should be a dllexport'd object. */ |
101 | 101 |
102 static bool | 102 static bool |
103 i386_pe_determine_dllexport_p (tree decl) | 103 i386_pe_determine_dllexport_p (tree decl) |
104 { | 104 { |
105 tree assoc; | |
106 | |
107 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) | 105 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) |
108 return false; | 106 return false; |
109 | 107 |
108 /* Don't export local clones of dllexports. */ | |
109 if (!TREE_PUBLIC (decl)) | |
110 return false; | |
111 | |
110 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) | 112 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) |
111 return true; | 113 return true; |
112 | 114 |
113 /* Also mark class members of exported classes with dllexport. */ | |
114 assoc = associated_type (decl); | |
115 if (assoc && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (assoc))) | |
116 return i386_pe_type_dllexport_p (decl); | |
117 | |
118 return false; | 115 return false; |
119 } | 116 } |
120 | 117 |
121 /* Return true if DECL should be a dllimport'd object. */ | 118 /* Return true if DECL should be a dllimport'd object. */ |
122 | 119 |
126 tree assoc; | 123 tree assoc; |
127 | 124 |
128 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) | 125 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) |
129 return false; | 126 return false; |
130 | 127 |
131 /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag. | |
132 We may need to override an earlier decision. */ | |
133 if (DECL_DLLIMPORT_P (decl)) | 128 if (DECL_DLLIMPORT_P (decl)) |
134 return true; | 129 return true; |
135 | 130 |
136 /* The DECL_DLLIMPORT_P flag was set for decls in the class definition | 131 /* The DECL_DLLIMPORT_P flag was set for decls in the class definition |
137 by targetm.cxx.adjust_class_at_definition. Check again to emit | 132 by targetm.cxx.adjust_class_at_definition. Check again to emit |
138 warnings if the class attribute has been overridden by an | 133 error message if the class attribute has been overridden by an |
139 out-of-class definition. */ | 134 out-of-class definition of static data. */ |
140 assoc = associated_type (decl); | 135 assoc = associated_type (decl); |
141 if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))) | 136 if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)) |
142 return i386_pe_type_dllimport_p (decl); | 137 && TREE_CODE (decl) == VAR_DECL |
138 && TREE_STATIC (decl) && TREE_PUBLIC (decl) | |
139 && !DECL_EXTERNAL (decl) | |
140 /* vtable's are linkonce constants, so defining a vtable is not | |
141 an error as long as we don't try to import it too. */ | |
142 && !DECL_VIRTUAL_P (decl)) | |
143 error ("definition of static data member %q+D of " | |
144 "dllimport'd class", decl); | |
143 | 145 |
144 return false; | 146 return false; |
145 } | 147 } |
146 | 148 |
147 /* Handle the -mno-fun-dllimport target switch. */ | 149 /* Handle the -mno-fun-dllimport target switch. */ |
283 initialization and destruction code for it is present in | 285 initialization and destruction code for it is present in |
284 each unit defining the object. The code that calls the | 286 each unit defining the object. The code that calls the |
285 ctor is protected by a link-once guard variable, so that | 287 ctor is protected by a link-once guard variable, so that |
286 the object still has link-once semantics, */ | 288 the object still has link-once semantics, */ |
287 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) | 289 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) |
288 make_decl_one_only (decl); | 290 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); |
289 else | 291 else |
290 error ("%q+D:'selectany' attribute applies only to " | 292 error ("%q+D:'selectany' attribute applies only to " |
291 "initialized objects", decl); | 293 "initialized objects", decl); |
292 } | 294 } |
293 break; | 295 break; |
302 flags = (SYMBOL_REF_FLAGS (symbol) & | 304 flags = (SYMBOL_REF_FLAGS (symbol) & |
303 ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT)); | 305 ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT)); |
304 if (i386_pe_determine_dllexport_p (decl)) | 306 if (i386_pe_determine_dllexport_p (decl)) |
305 flags |= SYMBOL_FLAG_DLLEXPORT; | 307 flags |= SYMBOL_FLAG_DLLEXPORT; |
306 else if (i386_pe_determine_dllimport_p (decl)) | 308 else if (i386_pe_determine_dllimport_p (decl)) |
307 { | 309 flags |= SYMBOL_FLAG_DLLIMPORT; |
308 flags |= SYMBOL_FLAG_DLLIMPORT; | 310 |
309 /* If we went through the associated_type path, this won't already | |
310 be set. Though, frankly, this seems wrong, and should be fixed | |
311 elsewhere. */ | |
312 if (!DECL_DLLIMPORT_P (decl)) | |
313 { | |
314 DECL_DLLIMPORT_P (decl) = 1; | |
315 flags &= ~SYMBOL_FLAG_LOCAL; | |
316 } | |
317 } | |
318 SYMBOL_REF_FLAGS (symbol) = flags; | 311 SYMBOL_REF_FLAGS (symbol) = flags; |
319 } | 312 } |
320 | 313 |
321 bool | 314 bool |
322 i386_pe_binds_local_p (const_tree exp) | 315 i386_pe_binds_local_p (const_tree exp) |
497 const char *name, HOST_WIDE_INT size, | 490 const char *name, HOST_WIDE_INT size, |
498 HOST_WIDE_INT align ATTRIBUTE_UNUSED) | 491 HOST_WIDE_INT align ATTRIBUTE_UNUSED) |
499 { | 492 { |
500 HOST_WIDE_INT rounded; | 493 HOST_WIDE_INT rounded; |
501 | 494 |
502 /* Compute as in assemble_noswitch_variable, since we don't actually | 495 /* Compute as in assemble_noswitch_variable, since we don't have |
503 support aligned common. */ | 496 support for aligned common on older binutils. We must also |
497 avoid emitting a common symbol of size zero, as this is the | |
498 overloaded representation that indicates an undefined external | |
499 symbol in the PE object file format. */ | |
504 rounded = size ? size : 1; | 500 rounded = size ? size : 1; |
505 rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1; | 501 rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1; |
506 rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT) | 502 rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT) |
507 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); | 503 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); |
508 | 504 |
509 i386_pe_maybe_record_exported_symbol (decl, name, 1); | 505 i386_pe_maybe_record_exported_symbol (decl, name, 1); |
510 | 506 |
511 fprintf (stream, "\t.comm\t"); | 507 fprintf (stream, "\t.comm\t"); |
512 assemble_name (stream, name); | 508 assemble_name (stream, name); |
513 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START | 509 if (use_pe_aligned_common) |
514 " " HOST_WIDE_INT_PRINT_DEC "\n", | 510 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n", |
515 rounded, size); | 511 size ? size : (HOST_WIDE_INT) 1, |
512 exact_log2 (align) - exact_log2 (CHAR_BIT)); | |
513 else | |
514 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START | |
515 " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size); | |
516 } | 516 } |
517 | 517 |
518 /* The Microsoft linker requires that every function be marked as | 518 /* The Microsoft linker requires that every function be marked as |
519 DT_FCN. When using gas on cygwin, we must emit appropriate .type | 519 DT_FCN. When using gas on cygwin, we must emit appropriate .type |
520 directives. */ | 520 directives. */ |
537 (int) DT_FCN << N_BTSHFT); | 537 (int) DT_FCN << N_BTSHFT); |
538 } | 538 } |
539 | 539 |
540 /* Keep a list of external functions. */ | 540 /* Keep a list of external functions. */ |
541 | 541 |
542 struct extern_list GTY(()) | 542 struct GTY(()) extern_list |
543 { | 543 { |
544 struct extern_list *next; | 544 struct extern_list *next; |
545 tree decl; | 545 tree decl; |
546 const char *name; | 546 const char *name; |
547 }; | 547 }; |
566 extern_head = p; | 566 extern_head = p; |
567 } | 567 } |
568 | 568 |
569 /* Keep a list of exported symbols. */ | 569 /* Keep a list of exported symbols. */ |
570 | 570 |
571 struct export_list GTY(()) | 571 struct GTY(()) export_list |
572 { | 572 { |
573 struct export_list *next; | 573 struct export_list *next; |
574 const char *name; | 574 const char *name; |
575 int is_data; /* used to type tag exported symbols. */ | 575 int is_data; /* used to type tag exported symbols. */ |
576 }; | 576 }; |
592 symbol = XEXP (DECL_RTL (decl), 0); | 592 symbol = XEXP (DECL_RTL (decl), 0); |
593 gcc_assert (GET_CODE (symbol) == SYMBOL_REF); | 593 gcc_assert (GET_CODE (symbol) == SYMBOL_REF); |
594 if (!SYMBOL_REF_DLLEXPORT_P (symbol)) | 594 if (!SYMBOL_REF_DLLEXPORT_P (symbol)) |
595 return; | 595 return; |
596 | 596 |
597 gcc_assert (TREE_PUBLIC (decl)); | |
598 | |
597 p = (struct export_list *) ggc_alloc (sizeof *p); | 599 p = (struct export_list *) ggc_alloc (sizeof *p); |
598 p->next = export_head; | 600 p->next = export_head; |
599 p->name = name; | 601 p->name = name; |
600 p->is_data = is_data; | 602 p->is_data = is_data; |
601 export_head = p; | 603 export_head = p; |
602 } | 604 } |
603 | 605 |
606 #ifdef CXX_WRAP_SPEC_LIST | |
607 | |
608 /* Hash table equality helper function. */ | |
609 | |
610 static int | |
611 wrapper_strcmp (const void *x, const void *y) | |
612 { | |
613 return !strcmp ((const char *) x, (const char *) y); | |
614 } | |
615 | |
616 /* Search for a function named TARGET in the list of library wrappers | |
617 we are using, returning a pointer to it if found or NULL if not. | |
618 This function might be called on quite a few symbols, and we only | |
619 have the list of names of wrapped functions available to us as a | |
620 spec string, so first time round we lazily initialise a hash table | |
621 to make things quicker. */ | |
622 | |
623 static const char * | |
624 i386_find_on_wrapper_list (const char *target) | |
625 { | |
626 static char first_time = 1; | |
627 static htab_t wrappers; | |
628 | |
629 if (first_time) | |
630 { | |
631 /* Beware that this is not a complicated parser, it assumes | |
632 that any sequence of non-whitespace beginning with an | |
633 underscore is one of the wrapped symbols. For now that's | |
634 adequate to distinguish symbols from spec substitutions | |
635 and command-line options. */ | |
636 static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST; | |
637 char *bufptr; | |
638 /* Breaks up the char array into separated strings | |
639 strings and enter them into the hash table. */ | |
640 wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp, | |
641 0, xcalloc, free); | |
642 for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr) | |
643 { | |
644 char *found = NULL; | |
645 if (ISSPACE (*bufptr)) | |
646 continue; | |
647 if (*bufptr == '_') | |
648 found = bufptr; | |
649 while (*bufptr && !ISSPACE (*bufptr)) | |
650 ++bufptr; | |
651 if (*bufptr) | |
652 *bufptr = 0; | |
653 if (found) | |
654 *htab_find_slot (wrappers, found, INSERT) = found; | |
655 } | |
656 first_time = 0; | |
657 } | |
658 | |
659 return (const char *) htab_find (wrappers, target); | |
660 } | |
661 | |
662 #endif /* CXX_WRAP_SPEC_LIST */ | |
663 | |
604 /* This is called at the end of assembly. For each external function | 664 /* This is called at the end of assembly. For each external function |
605 which has not been defined, we output a declaration now. We also | 665 which has not been defined, we output a declaration now. We also |
606 output the .drectve section. */ | 666 output the .drectve section. */ |
607 | 667 |
608 void | 668 void |
620 | 680 |
621 /* Positively ensure only one declaration for any given symbol. */ | 681 /* Positively ensure only one declaration for any given symbol. */ |
622 if (! TREE_ASM_WRITTEN (decl) | 682 if (! TREE_ASM_WRITTEN (decl) |
623 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) | 683 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) |
624 { | 684 { |
685 #ifdef CXX_WRAP_SPEC_LIST | |
686 /* To ensure the DLL that provides the corresponding real | |
687 functions is still loaded at runtime, we must reference | |
688 the real function so that an (unused) import is created. */ | |
689 const char *realsym = i386_find_on_wrapper_list (p->name); | |
690 if (realsym) | |
691 i386_pe_declare_function_type (asm_out_file, | |
692 concat ("__real_", realsym, NULL), TREE_PUBLIC (decl)); | |
693 #endif /* CXX_WRAP_SPEC_LIST */ | |
625 TREE_ASM_WRITTEN (decl) = 1; | 694 TREE_ASM_WRITTEN (decl) = 1; |
626 i386_pe_declare_function_type (asm_out_file, p->name, | 695 i386_pe_declare_function_type (asm_out_file, p->name, |
627 TREE_PUBLIC (decl)); | 696 TREE_PUBLIC (decl)); |
628 } | 697 } |
629 } | 698 } |