aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config/i386/winnt-cxx.c
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
committerBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
commit1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch)
treec607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/gcc/config/i386/winnt-cxx.c
parent283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff)
downloadtoolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/gcc/config/i386/winnt-cxx.c')
-rw-r--r--gcc-4.9/gcc/config/i386/winnt-cxx.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/i386/winnt-cxx.c b/gcc-4.9/gcc/config/i386/winnt-cxx.c
new file mode 100644
index 000000000..aa75f9157
--- /dev/null
+++ b/gcc-4.9/gcc/config/i386/winnt-cxx.c
@@ -0,0 +1,184 @@
+/* Target support for C++ classes on Windows.
+ Contributed by Danny Smith (dannysmith@users.sourceforge.net)
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "cp/cp-tree.h" /* This is why we're a separate module. */
+#include "flags.h"
+#include "tm_p.h"
+#include "diagnostic-core.h"
+#include "hashtab.h"
+
+bool
+i386_pe_type_dllimport_p (tree decl)
+{
+ gcc_assert (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == FUNCTION_DECL);
+
+ if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
+ return false;
+
+ /* We ignore the dllimport attribute for inline member functions.
+ This differs from MSVC behavior which treats it like GNUC
+ 'extern inline' extension. Also ignore for template
+ instantiations with linkonce semantics and artificial methods. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && (DECL_DECLARED_INLINE_P (decl)
+ || DECL_TEMPLATE_INSTANTIATION (decl)
+ || DECL_ARTIFICIAL (decl)))
+ return false;
+
+ /* Overrides of the class dllimport decls by out-of-class definitions are
+ handled by tree.c:merge_dllimport_decl_attributes. */
+ return true;
+}
+
+bool
+i386_pe_type_dllexport_p (tree decl)
+{
+ gcc_assert (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == FUNCTION_DECL);
+
+ /* Avoid exporting compiler-generated default dtors and copy ctors.
+ The only artificial methods that need to be exported are virtual
+ and non-virtual thunks. */
+ if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
+ && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl))
+ return false;
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl))
+ {
+ if (DECL_REALLY_EXTERN (decl)
+ || !flag_keep_inline_dllexport)
+ return false;
+ }
+ return true;
+}
+
+static inline void maybe_add_dllimport (tree decl)
+{
+ if (i386_pe_type_dllimport_p (decl))
+ DECL_DLLIMPORT_P (decl) = 1;
+}
+
+static inline void maybe_add_dllexport (tree decl)
+{
+ if (i386_pe_type_dllexport_p (decl))
+ {
+ tree decl_attrs = DECL_ATTRIBUTES (decl);
+ if (lookup_attribute ("dllexport", decl_attrs) != NULL_TREE)
+ /* Already done. */
+ return;
+ DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("dllexport"),
+ NULL_TREE, decl_attrs);
+ }
+}
+
+void
+i386_pe_adjust_class_at_definition (tree t)
+{
+ tree member;
+
+ gcc_assert (CLASS_TYPE_P (t));
+
+
+ if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
+ {
+ tree tmv = TYPE_MAIN_VARIANT (t);
+
+ /* Make sure that we set dllexport attribute to typeinfo's
+ base declaration, as otherwise it would fail to be exported as
+ it isn't a class-member. */
+ if (tmv != NULL_TREE
+ && CLASSTYPE_TYPEINFO_VAR (tmv) != NULL_TREE)
+ {
+ tree na, ti_decl = CLASSTYPE_TYPEINFO_VAR (tmv);
+ na = tree_cons (get_identifier ("dllexport"), NULL_TREE,
+ NULL_TREE);
+ decl_attributes (&ti_decl, na, 0);
+ }
+
+ /* Check static VAR_DECL's. */
+ for (member = TYPE_FIELDS (t); member; member = DECL_CHAIN (member))
+ if (TREE_CODE (member) == VAR_DECL)
+ maybe_add_dllexport (member);
+
+ /* Check FUNCTION_DECL's. */
+ for (member = TYPE_METHODS (t); member; member = DECL_CHAIN (member))
+ if (TREE_CODE (member) == FUNCTION_DECL)
+ {
+ tree thunk;
+ maybe_add_dllexport (member);
+
+ /* Also add the attribute to its thunks. */
+ for (thunk = DECL_THUNKS (member); thunk;
+ thunk = TREE_CHAIN (thunk))
+ maybe_add_dllexport (thunk);
+ }
+ /* Check vtables */
+ for (member = CLASSTYPE_VTABLES (t); member; member = DECL_CHAIN (member))
+ if (TREE_CODE (member) == VAR_DECL)
+ maybe_add_dllexport (member);
+ }
+
+ else if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
+ {
+ /* We don't actually add the attribute to the decl, just set the flag
+ that signals that the address of this symbol is not a compile-time
+ constant. Any subsequent out-of-class declaration of members wil
+ cause the DECL_DLLIMPORT_P flag to be unset.
+ (See tree.c: merge_dllimport_decl_attributes).
+ That is just right since out-of class declarations can only be a
+ definition. */
+
+ /* Check static VAR_DECL's. */
+ for (member = TYPE_FIELDS (t); member; member = DECL_CHAIN (member))
+ if (TREE_CODE (member) == VAR_DECL)
+ maybe_add_dllimport (member);
+
+ /* Check FUNCTION_DECL's. */
+ for (member = TYPE_METHODS (t); member; member = DECL_CHAIN (member))
+ if (TREE_CODE (member) == FUNCTION_DECL)
+ {
+ tree thunk;
+ maybe_add_dllimport (member);
+
+ /* Also add the attribute to its thunks. */
+ for (thunk = DECL_THUNKS (member); thunk;
+ thunk = DECL_CHAIN (thunk))
+ maybe_add_dllimport (thunk);
+ }
+
+ /* Check vtables */
+ for (member = CLASSTYPE_VTABLES (t); member; member = DECL_CHAIN (member))
+ if (TREE_CODE (member) == VAR_DECL)
+ maybe_add_dllimport (member);
+
+ /* We leave typeinfo tables alone. We can't mark TI objects as
+ dllimport, since the address of a secondary VTT may be needed
+ for static initialization of a primary VTT. VTT's of
+ dllimport'd classes should always be link-once COMDAT. */
+ }
+}