1130636Srwatson/* Target support for C++ classes on Windows. 2101242Srwatson Contributed by Danny Smith (dannysmith@users.sourceforge.net) 3107603Sru Copyright (C) 2005 4101242Srwatson Free Software Foundation, Inc. 5101242Srwatson 6101242SrwatsonThis file is part of GCC. 7101242Srwatson 8101242SrwatsonGCC is free software; you can redistribute it and/or modify it under 9107603Sruthe terms of the GNU General Public License as published by the Free 10101242SrwatsonSoftware Foundation; either version 2, or (at your option) any later 11101242Srwatsonversion. 12101242Srwatson 13101242SrwatsonGCC is distributed in the hope that it will be useful, but WITHOUT ANY 14101242SrwatsonWARRANTY; without even the implied warranty of MERCHANTABILITY or 15101242SrwatsonFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16101242Srwatsonfor more details. 17101242Srwatson 18107603SruYou should have received a copy of the GNU General Public License 19101242Srwatsonalong with GCC; see the file COPYING. If not, write to 20101242Srwatsonthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 21101242SrwatsonBoston, MA 02110-1301, USA. */ 22101242Srwatson 23101242Srwatson#include "config.h" 24101242Srwatson#include "system.h" 25101242Srwatson#include "coretypes.h" 26101242Srwatson#include "tm.h" 27101242Srwatson#include "rtl.h" 28101242Srwatson#include "regs.h" 29101242Srwatson#include "hard-reg-set.h" 30107603Sru#include "output.h" 31101242Srwatson#include "tree.h" 32107603Sru#include "cp/cp-tree.h" /* this is why we're a separate module */ 33101242Srwatson#include "flags.h" 34101242Srwatson#include "tm_p.h" 35107744Sru#include "toplev.h" 36101242Srwatson#include "hashtab.h" 37101242Srwatson 38130636Srwatsonbool 39101242Srwatsoni386_pe_type_dllimport_p (tree decl) 40131365Sru{ 41131365Sru gcc_assert (TREE_CODE (decl) == VAR_DECL 42101242Srwatson || TREE_CODE (decl) == FUNCTION_DECL); 43101242Srwatson 44107603Sru if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL) 45107603Sru return false; 46101242Srwatson 47101242Srwatson /* We ignore the dllimport attribute for inline member functions. 48109263Schris This differs from MSVC behavior which treats it like GNUC 49109263Schris 'extern inline' extension. Also ignore for template 50109263Schris instantiations with linkonce semantics and artificial methods. */ 51130636Srwatson if (TREE_CODE (decl) == FUNCTION_DECL 52130636Srwatson && (DECL_DECLARED_INLINE_P (decl) 53109263Schris || DECL_TEMPLATE_INSTANTIATION (decl) 54109263Schris || DECL_ARTIFICIAL (decl))) 55122810Srwatson return false; 56122810Srwatson 57109263Schris /* Since we can't treat a pointer to a dllimport'd symbol as a 58109263Schris constant address, we turn off the attribute on C++ virtual 59109263Schris methods to allow creation of vtables using thunks. */ 60101242Srwatson else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE 61101242Srwatson && DECL_VIRTUAL_P (decl)) 62101242Srwatson { 63122810Srwatson /* Even though we ignore the attribute from the start, warn if we later see 64122810Srwatson an out-of class definition, as we do for other member functions in 65130636Srwatson tree.c:merge_dllimport_decl_attributes. If this is the key method, the 66131365Sru definition may affect the import-export status of vtables, depending 67130636Srwatson on how we handle MULTIPLE_SYMBOL_SPACES in cp/decl2.c. */ 68130636Srwatson if (DECL_INITIAL (decl)) 69130636Srwatson { 70122810Srwatson warning (OPT_Wattributes, "%q+D redeclared without dllimport attribute: " 71122810Srwatson "previous dllimport ignored", decl); 72101242Srwatson#ifdef PE_DLL_DEBUG 73122810Srwatson if (decl == CLASSTYPE_KEY_METHOD (DECL_CONTEXT (decl))) 74122810Srwatson warning (OPT_Wattributes, "key method %q+D of dllimport'd class defined" 75122810Srwatson decl); 76122810Srwatson#endif 77122810Srwatson } 78122810Srwatson return false; 79122810Srwatson } 80122810Srwatson 81122810Srwatson /* Don't mark defined functions as dllimport. This code will only be 82122810Srwatson reached if we see a non-inline function defined out-of-class. */ 83122810Srwatson else if (TREE_CODE (decl) == FUNCTION_DECL 84122810Srwatson && (DECL_INITIAL (decl))) 85109263Schris return false; 86101242Srwatson 87122810Srwatson /* Don't allow definitions of static data members in dllimport class, 88122810Srwatson If vtable data is marked as DECL_EXTERNAL, import it; otherwise just 89101242Srwatson ignore the class attribute. */ 90122810Srwatson else if (TREE_CODE (decl) == VAR_DECL 91131365Sru && TREE_STATIC (decl) && TREE_PUBLIC (decl) 92122810Srwatson && !DECL_EXTERNAL (decl)) 93122810Srwatson { 94122810Srwatson if (!DECL_VIRTUAL_P (decl)) 95122810Srwatson error ("definition of static data member %q+D of " 96122810Srwatson "dllimport'd class", decl); 97122810Srwatson return false; 98122810Srwatson } 99122810Srwatson 100101242Srwatson return true; 101101242Srwatson} 102101242Srwatson 103101242Srwatson 104109263Schrisbool 105101242Srwatsoni386_pe_type_dllexport_p (tree decl) 106101242Srwatson{ 107101242Srwatson gcc_assert (TREE_CODE (decl) == VAR_DECL 108122810Srwatson || TREE_CODE (decl) == FUNCTION_DECL); 109122810Srwatson /* Avoid exporting compiler-generated default dtors and copy ctors. 110122810Srwatson The only artificial methods that need to be exported are virtual 111101242Srwatson and non-virtual thunks. */ 112101242Srwatson if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE 113109263Schris && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl)) 114101242Srwatson return false; 115101242Srwatson return true; 116101242Srwatson} 117101242Srwatson 118101242Srwatsonstatic inline void maybe_add_dllimport (tree decl) 119101242Srwatson{ 120109263Schris if (i386_pe_type_dllimport_p (decl)) 121101242Srwatson DECL_DLLIMPORT_P (decl) = 1; 122101242Srwatson} 123101242Srwatson 124101242Srwatsonvoid 125101242Srwatsoni386_pe_adjust_class_at_definition (tree t) 126101242Srwatson{ 127109263Schris tree member; 128101242Srwatson 129101242Srwatson gcc_assert (CLASS_TYPE_P (t)); 130101242Srwatson 131101242Srwatson /* We only look at dllimport. The only thing that dllexport does is 132101242Srwatson add stuff to a '.drectiv' section at end-of-file, so no need to do 133109263Schris anything for dllexport'd classes until we generate RTL. */ 134107603Sru if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) == NULL_TREE) 135120010Sru return; 136196123Srwatson 137109273Schris /* We don't actually add the attribute to the decl, just set the flag 138109263Schris that signals that the address of this symbol is not a compile-time 139101242Srwatson constant. Any subsequent out-of-class declaration of members wil 140101242Srwatson cause the DECL_DLLIMPORT_P flag to be unset. 141101242Srwatson (See tree.c: merge_dllimport_decl_attributes). 142101242Srwatson That is just right since out-of class declarations can only be a 143101242Srwatson definition. We recheck the class members at RTL generation to 144101242Srwatson emit warnings if this has happened. Definition of static data member 145101242Srwatson of dllimport'd class always causes an error (as per MS compiler). 146101242Srwatson */ 147119321Srwatson 148119321Srwatson /* Check static VAR_DECL's. */ 149119321Srwatson for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) 150119321Srwatson if (TREE_CODE (member) == VAR_DECL) 151119321Srwatson maybe_add_dllimport (member); 152119321Srwatson 153 /* Check FUNCTION_DECL's. */ 154 for (member = TYPE_METHODS (t); member; member = TREE_CHAIN (member)) 155 if (TREE_CODE (member) == FUNCTION_DECL) 156 maybe_add_dllimport (member); 157 158 /* Check vtables */ 159 for (member = CLASSTYPE_VTABLES (t); member; member = TREE_CHAIN (member)) 160 if (TREE_CODE (member) == VAR_DECL) 161 maybe_add_dllimport (member); 162 163/* We leave typeinfo tables alone. We can't mark TI objects as 164 dllimport, since the address of a secondary VTT may be needed 165 for static initialization of a primary VTT. VTT's of 166 dllimport'd classes should always be link-once COMDAT. */ 167} 168