From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/config/i386/winnt-cxx.c | 175 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 gcc/config/i386/winnt-cxx.c (limited to 'gcc/config/i386/winnt-cxx.c') diff --git a/gcc/config/i386/winnt-cxx.c b/gcc/config/i386/winnt-cxx.c new file mode 100644 index 000000000..0c47e3a8b --- /dev/null +++ b/gcc/config/i386/winnt-cxx.c @@ -0,0 +1,175 @@ +/* Target support for C++ classes on Windows. + Contributed by Danny Smith (dannysmith@users.sourceforge.net) + Copyright (C) 2005, 2007, 2009, 2010 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 +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.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; + 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. */ + } +} -- cgit v1.2.3