]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/winnt-cxx.c
* diagnostic-core.h: Include bversion.h.
[thirdparty/gcc.git] / gcc / config / i386 / winnt-cxx.c
CommitLineData
6c1e551f 1/* Target support for C++ classes on Windows.
2 Contributed by Danny Smith (dannysmith@users.sourceforge.net)
92468061 3 Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
6c1e551f 4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
038d1e19 9Software Foundation; either version 3, or (at your option) any later
6c1e551f 10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
038d1e19 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
2a323463 20
6c1e551f 21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
6c1e551f 25#include "tree.h"
f787a6a3 26#include "cp/cp-tree.h" /* This is why we're a separate module. */
6c1e551f 27#include "flags.h"
28#include "tm_p.h"
0b205f4c 29#include "diagnostic-core.h"
6c1e551f 30#include "hashtab.h"
31
32bool
33i386_pe_type_dllimport_p (tree decl)
34{
f5b1f90b 35 gcc_assert (TREE_CODE (decl) == VAR_DECL
36 || TREE_CODE (decl) == FUNCTION_DECL);
37
38 if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
39 return false;
40
41 /* We ignore the dllimport attribute for inline member functions.
42 This differs from MSVC behavior which treats it like GNUC
43 'extern inline' extension. Also ignore for template
44 instantiations with linkonce semantics and artificial methods. */
45 if (TREE_CODE (decl) == FUNCTION_DECL
46 && (DECL_DECLARED_INLINE_P (decl)
47 || DECL_TEMPLATE_INSTANTIATION (decl)
48 || DECL_ARTIFICIAL (decl)))
49 return false;
f787a6a3 50
51 /* Overrides of the class dllimport decls by out-of-class definitions are
52 handled by tree.c:merge_dllimport_decl_attributes. */
f5b1f90b 53 return true;
6c1e551f 54}
55
6c1e551f 56bool
57i386_pe_type_dllexport_p (tree decl)
58{
f787a6a3 59 gcc_assert (TREE_CODE (decl) == VAR_DECL
60 || TREE_CODE (decl) == FUNCTION_DECL);
61
62 /* Avoid exporting compiler-generated default dtors and copy ctors.
63 The only artificial methods that need to be exported are virtual
64 and non-virtual thunks. */
65 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
66 && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl))
67 return false;
68 return true;
6c1e551f 69}
70
71static inline void maybe_add_dllimport (tree decl)
72{
73 if (i386_pe_type_dllimport_p (decl))
f787a6a3 74 DECL_DLLIMPORT_P (decl) = 1;
75}
76
77static inline void maybe_add_dllexport (tree decl)
78{
79 if (i386_pe_type_dllexport_p (decl))
80 {
81 tree decl_attrs = DECL_ATTRIBUTES (decl);
82 if (lookup_attribute ("dllexport", decl_attrs) != NULL_TREE)
83 /* Already done. */
84 return;
85 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("dllexport"),
86 NULL_TREE, decl_attrs);
87 }
6c1e551f 88}
89
90void
91i386_pe_adjust_class_at_definition (tree t)
92{
93 tree member;
94
95 gcc_assert (CLASS_TYPE_P (t));
f787a6a3 96
97
98 if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
99 {
100 /* Check static VAR_DECL's. */
1767a056 101 for (member = TYPE_FIELDS (t); member; member = DECL_CHAIN (member))
f787a6a3 102 if (TREE_CODE (member) == VAR_DECL)
103 maybe_add_dllexport (member);
104
105 /* Check FUNCTION_DECL's. */
1767a056 106 for (member = TYPE_METHODS (t); member; member = DECL_CHAIN (member))
f787a6a3 107 if (TREE_CODE (member) == FUNCTION_DECL)
108 {
109 tree thunk;
110 maybe_add_dllexport (member);
111
112 /* Also add the attribute to its thunks. */
113 for (thunk = DECL_THUNKS (member); thunk;
114 thunk = TREE_CHAIN (thunk))
115 maybe_add_dllexport (thunk);
116 }
117 /* Check vtables */
1767a056 118 for (member = CLASSTYPE_VTABLES (t); member; member = DECL_CHAIN (member))
f787a6a3 119 if (TREE_CODE (member) == VAR_DECL)
120 maybe_add_dllexport (member);
121 }
6c1e551f 122
f787a6a3 123 else if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
124 {
125 /* We don't actually add the attribute to the decl, just set the flag
126 that signals that the address of this symbol is not a compile-time
127 constant. Any subsequent out-of-class declaration of members wil
128 cause the DECL_DLLIMPORT_P flag to be unset.
129 (See tree.c: merge_dllimport_decl_attributes).
130 That is just right since out-of class declarations can only be a
131 definition. */
132
133 /* Check static VAR_DECL's. */
1767a056 134 for (member = TYPE_FIELDS (t); member; member = DECL_CHAIN (member))
f787a6a3 135 if (TREE_CODE (member) == VAR_DECL)
136 maybe_add_dllimport (member);
6c1e551f 137
f787a6a3 138 /* Check FUNCTION_DECL's. */
1767a056 139 for (member = TYPE_METHODS (t); member; member = DECL_CHAIN (member))
f787a6a3 140 if (TREE_CODE (member) == FUNCTION_DECL)
141 {
142 tree thunk;
143 maybe_add_dllimport (member);
144
145 /* Also add the attribute to its thunks. */
146 for (thunk = DECL_THUNKS (member); thunk;
1767a056 147 thunk = DECL_CHAIN (thunk))
f787a6a3 148 maybe_add_dllimport (thunk);
149 }
6c1e551f 150
f787a6a3 151 /* Check vtables */
1767a056 152 for (member = CLASSTYPE_VTABLES (t); member; member = DECL_CHAIN (member))
f787a6a3 153 if (TREE_CODE (member) == VAR_DECL)
154 maybe_add_dllimport (member);
155
156 /* We leave typeinfo tables alone. We can't mark TI objects as
157 dllimport, since the address of a secondary VTT may be needed
158 for static initialization of a primary VTT. VTT's of
159 dllimport'd classes should always be link-once COMDAT. */
160 }
6c1e551f 161}