1 /* Routines for GCC for a Symbian OS targeted SH backend.
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 Most of this code is stolen from i386/winnt.c.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published
10 by the Free Software Foundation; either version 2, or (at your
11 option) any later version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
25 #include "coretypes.h"
33 #include "cp/cp-tree.h" /* We need access to the OVL_... macros. */
36 /* Select the level of debugging information to display.
38 1 for informative messages about decisions to add attributes
39 2 for verbose information about what is being done. */
40 #define SYMBIAN_DEBUG 0
41 //#define SYMBIAN_DEBUG 1
42 //#define SYMBIAN_DEBUG 2
44 /* A unique character to encode declspec encoded objects. */
45 #define SH_SYMBIAN_FLAG_CHAR "$"
47 /* Unique strings to prefix exported and imported objects. */
48 #define DLL_IMPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "i."
49 #define DLL_EXPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "e."
52 /* Return the type that we should use to determine if DECL is
53 imported or exported. */
56 sh_symbian_associated_type (tree decl)
60 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
61 /* Methods now inherit their dllimport/dllexport attributes correctly
62 so there is no need to check their class. In fact it is wrong to
63 check their class since a method can remain unexported from an
67 /* Otherwise we can just take the DECL_CONTEXT as normal. */
68 if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
69 t = DECL_CONTEXT (decl);
74 /* Return nonzero if DECL is a dllexport'd object. */
77 sh_symbian_dllexport_p (tree decl)
81 if ( TREE_CODE (decl) != VAR_DECL
82 && TREE_CODE (decl) != FUNCTION_DECL)
85 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
87 /* Class members get the dllexport status of their class. */
90 tree class = sh_symbian_associated_type (decl);
93 exp = lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class));
98 print_node_brief (stderr, "dllexport:", decl, 0);
99 fprintf (stderr, "\n");
102 #if SYMBIAN_DEBUG < 2
103 if (TREE_CODE (decl) != FUNCTION_DECL)
106 print_node_brief (stderr, "no dllexport:", decl, 0);
107 fprintf (stderr, "\n");
110 return exp ? true : false;
113 /* Return nonzero if DECL is a dllimport'd object. */
116 sh_symbian_dllimport_p (tree decl)
120 if ( TREE_CODE (decl) != VAR_DECL
121 && TREE_CODE (decl) != FUNCTION_DECL)
124 imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
128 /* Class members get the dllimport status of their class. */
129 imp = sh_symbian_associated_type (decl);
133 imp = lookup_attribute ("dllimport", TYPE_ATTRIBUTES (imp));
137 /* Don't mark defined functions as dllimport. If the definition itself
138 was marked with dllimport, then sh_symbian_handle_dll_attribute reports
139 an error. This handles the case when the definition overrides an
140 earlier declaration. */
141 if (TREE_CODE (decl) == FUNCTION_DECL
142 && DECL_INITIAL (decl)
143 && !DECL_INLINE (decl))
145 /* Don't warn about artificial methods. */
146 if (!DECL_ARTIFICIAL (decl))
147 warning (OPT_Wattributes, "%H function '%D' is defined after prior "
148 "declaration as dllimport: attribute ignored",
149 & DECL_SOURCE_LOCATION (decl), decl);
153 /* We ignore the dllimport attribute for inline member functions.
154 This differs from MSVC behavior which treats it like GNUC
155 'extern inline' extension. */
156 else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
159 warning (OPT_Wattributes, "%Hinline function '%D' is declared as "
160 "dllimport: attribute ignored.",
161 & DECL_SOURCE_LOCATION (decl), decl);
165 /* Don't allow definitions of static data members in dllimport
166 class. Just ignore the attribute for vtable data. */
167 else if (TREE_CODE (decl) == VAR_DECL
168 && TREE_STATIC (decl)
169 && TREE_PUBLIC (decl)
170 && !DECL_EXTERNAL (decl))
172 if (!DECL_VIRTUAL_P (decl))
173 error ("%Hdefinition of static data member '%D' of dllimport'd class.",
174 & DECL_SOURCE_LOCATION (decl), decl);
178 /* Since we can't treat a pointer to a dllimport'd symbol as a
179 constant address, we turn off the attribute on C++ virtual
180 methods to allow creation of vtables using thunks. Don't mark
181 artificial methods either (in sh_symbian_associated_type, only
182 COMDAT artificial method get import status from class context). */
183 else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
184 && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
190 /* Return nonzero if SYMBOL is marked as being dllexport'd. */
193 sh_symbian_dllexport_name_p (const char *symbol)
195 return strncmp (DLL_EXPORT_PREFIX, symbol,
196 strlen (DLL_EXPORT_PREFIX)) == 0;
199 /* Return nonzero if SYMBOL is marked as being dllimport'd. */
203 sh_symbian_dllimport_name_p (const char *symbol)
205 return strncmp (DLL_IMPORT_PREFIX, symbol,
206 strlen (DLL_IMPORT_PREFIX)) == 0;
209 /* Mark a DECL as being dllexport'd.
210 Note that we override the previous setting (e.g.: dllimport). */
213 sh_symbian_mark_dllexport (tree decl)
220 rtlname = XEXP (DECL_RTL (decl), 0);
221 if (GET_CODE (rtlname) == MEM)
222 rtlname = XEXP (rtlname, 0);
223 gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
224 oldname = XSTR (rtlname, 0);
226 if (sh_symbian_dllimport_name_p (oldname))
228 /* Remove DLL_IMPORT_PREFIX.
229 Note - we do not issue a warning here. In Symbian's environment it
230 is legitimate for a prototype to be marked as dllimport and the
231 corresponding definition to be marked as dllexport. The prototypes
232 are in headers used everywhere and the definition is in a translation
233 unit which has included the header in order to ensure argument
235 oldname += strlen (DLL_IMPORT_PREFIX);
236 DECL_NON_ADDR_CONST_P (decl) = 0;
238 else if (sh_symbian_dllexport_name_p (oldname))
239 return; /* Already done. */
241 newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
242 sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
244 /* We pass newname through get_identifier to ensure it has a unique
245 address. RTL processing can sometimes peek inside the symbol ref
246 and compare the string's addresses to see if two symbols are
248 idp = get_identifier (newname);
250 XEXP (DECL_RTL (decl), 0) =
251 gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
254 /* Mark a DECL as being dllimport'd. */
257 sh_symbian_mark_dllimport (tree decl)
265 rtlname = XEXP (DECL_RTL (decl), 0);
266 if (GET_CODE (rtlname) == MEM)
267 rtlname = XEXP (rtlname, 0);
268 gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
269 oldname = XSTR (rtlname, 0);
271 if (sh_symbian_dllexport_name_p (oldname))
273 error ("%qs declared as both exported to and imported from a DLL",
274 IDENTIFIER_POINTER (DECL_NAME (decl)));
276 else if (sh_symbian_dllimport_name_p (oldname))
278 /* Already done, but do a sanity check to prevent assembler errors. */
279 if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
280 error ("%Hfailure in redeclaration of '%D': dllimport'd symbol lacks external linkage.",
281 &DECL_SOURCE_LOCATION (decl), decl);
285 newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
286 sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
288 /* We pass newname through get_identifier to ensure it has a unique
289 address. RTL processing can sometimes peek inside the symbol ref
290 and compare the string's addresses to see if two symbols are
292 idp = get_identifier (newname);
293 newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
294 XEXP (DECL_RTL (decl), 0) = newrtl;
299 sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
301 default_encode_section_info (decl, rtl, first);
303 /* Mark the decl so we can tell from the rtl whether
304 the object is dllexport'd or dllimport'd. */
305 if (sh_symbian_dllexport_p (decl))
306 sh_symbian_mark_dllexport (decl);
307 else if (sh_symbian_dllimport_p (decl))
308 sh_symbian_mark_dllimport (decl);
309 /* It might be that DECL has already been marked as dllimport, but a
310 subsequent definition nullified that. The attribute is gone but
311 DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
312 that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
313 else if ( (TREE_CODE (decl) == FUNCTION_DECL
314 || TREE_CODE (decl) == VAR_DECL)
315 && DECL_RTL (decl) != NULL_RTX
316 && GET_CODE (DECL_RTL (decl)) == MEM
317 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
318 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
319 && sh_symbian_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
321 const char * oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
322 /* Remove DLL_IMPORT_PREFIX. */
323 tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
324 rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
326 warning (0, "%H%s '%D' %s after being referenced with dllimport linkage.",
327 & DECL_SOURCE_LOCATION (decl),
328 TREE_CODE (decl) == VAR_DECL ? "variable" : "function",
329 decl, (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
330 ? "defined locally" : "redeclared without dllimport attribute");
332 XEXP (DECL_RTL (decl), 0) = newrtl;
334 DECL_NON_ADDR_CONST_P (decl) = 0;
339 /* Return the length of a function name prefix
340 that starts with the character 'c'. */
343 sh_symbian_get_strip_length (int c)
345 /* XXX Assumes strlen (DLL_EXPORT_PREFIX) == strlen (DLL_IMPORT_PREFIX). */
346 return (c == SH_SYMBIAN_FLAG_CHAR[0]) ? strlen (DLL_EXPORT_PREFIX) : 0;
349 /* Return a pointer to a function's name with any
350 and all prefix encodings stripped from it. */
353 sh_symbian_strip_name_encoding (const char *name)
357 while ((skip = sh_symbian_get_strip_length (*name)))
363 /* Add the named attribute to the given node. Copes with both DECLs and
364 TYPEs. Will only add the attribute if it is not already present. */
367 symbian_add_attribute (tree node, const char *attr_name)
372 attrs = DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node);
374 if (lookup_attribute (attr_name, attrs) != NULL_TREE)
377 attr = get_identifier (attr_name);
379 (DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node))
380 = tree_cons (attr, NULL_TREE, attrs);
383 fprintf (stderr, "propogate %s attribute", attr_name);
384 print_node_brief (stderr, " to", node, 0);
385 fprintf (stderr, "\n");
389 /* Handle a "dllimport" or "dllexport" attribute;
390 arguments as in struct attribute_spec.handler. */
393 sh_symbian_handle_dll_attribute (tree *pnode, tree name, tree args,
394 int flags, bool *no_add_attrs)
398 const char *attr = IDENTIFIER_POINTER (name);
400 /* These attributes may apply to structure and union types being
401 created, but otherwise should pass to the declaration involved. */
404 if (flags & ((int) ATTR_FLAG_DECL_NEXT
405 | (int) ATTR_FLAG_FUNCTION_NEXT
406 | (int) ATTR_FLAG_ARRAY_NEXT))
408 warning (OPT_Wattributes, "%qs attribute ignored", attr);
409 *no_add_attrs = true;
410 return tree_cons (name, args, NULL_TREE);
413 if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
415 warning (OPT_Wattributes, "%qs attribute ignored", attr);
416 *no_add_attrs = true;
422 /* Report error on dllimport ambiguities
423 seen now before they cause any damage. */
424 else if (is_attribute_p ("dllimport", name))
426 if (TREE_CODE (node) == VAR_DECL)
428 if (DECL_INITIAL (node))
430 error ("%Hvariable %qD definition is marked dllimport.",
431 & DECL_SOURCE_LOCATION (node), node);
432 *no_add_attrs = true;
435 /* `extern' needn't be specified with dllimport.
436 Specify `extern' now and hope for the best. Sigh. */
437 DECL_EXTERNAL (node) = 1;
438 /* Also, implicitly give dllimport'd variables declared within
439 a function global scope, unless declared static. */
440 if (current_function_decl != NULL_TREE && ! TREE_STATIC (node))
441 TREE_PUBLIC (node) = 1;
445 /* If the node is an overloaded constructor or destructor, then we must
446 make sure that the attribute is propagated along the overload chain,
447 as it is these overloaded functions which will be emitted, rather than
448 the user declared constructor itself. */
449 if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE
450 && (DECL_CONSTRUCTOR_P (node) || DECL_DESTRUCTOR_P (node)))
454 for (overload = OVL_CHAIN (node); overload; overload = OVL_CHAIN (overload))
458 tree function = OVL_CURRENT (overload);
461 || ! DECL_P (function)
462 || (DECL_CONSTRUCTOR_P (node) && ! DECL_CONSTRUCTOR_P (function))
463 || (DECL_DESTRUCTOR_P (node) && ! DECL_DESTRUCTOR_P (function)))
466 /* The arguments must match as well. */
467 for (node_args = DECL_ARGUMENTS (node), func_args = DECL_ARGUMENTS (function);
468 node_args && func_args;
469 node_args = TREE_CHAIN (node_args), func_args = TREE_CHAIN (func_args))
470 if (TREE_TYPE (node_args) != TREE_TYPE (func_args))
473 if (node_args || func_args)
475 /* We can ignore an extraneous __in_chrg arguments in the node.
476 GCC generated destructors, for example, will have this. */
477 if ((node_args == NULL_TREE
478 || func_args != NULL_TREE)
479 && strcmp (IDENTIFIER_POINTER (DECL_NAME (node)), "__in_chrg") != 0)
483 symbian_add_attribute (function, attr);
485 /* Propagate the attribute to any function thunks as well. */
486 for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
487 if (TREE_CODE (thunk) == FUNCTION_DECL)
488 symbian_add_attribute (thunk, attr);
492 if (TREE_CODE (node) == FUNCTION_DECL && DECL_VIRTUAL_P (node))
494 /* Propagate the attribute to any thunks of this function. */
495 for (thunk = DECL_THUNKS (node); thunk; thunk = TREE_CHAIN (thunk))
496 if (TREE_CODE (thunk) == FUNCTION_DECL)
497 symbian_add_attribute (thunk, attr);
500 /* Report error if symbol is not accessible at global scope. */
501 if (!TREE_PUBLIC (node)
502 && ( TREE_CODE (node) == VAR_DECL
503 || TREE_CODE (node) == FUNCTION_DECL))
505 error ("%Hexternal linkage required for symbol '%D' because of '%s' attribute.",
506 & DECL_SOURCE_LOCATION (node), node, IDENTIFIER_POINTER (name));
507 *no_add_attrs = true;
511 print_node_brief (stderr, "mark node", node, 0);
512 fprintf (stderr, " as %s\n", attr);
518 /* This code implements a specification for exporting the vtable and rtti of
519 classes that have members with the dllexport or dllexport attributes.
520 This specification is defined here:
522 http://www.armdevzone.com/EABI/exported_class.txt
524 Basically it says that a class's vtable and rtti should be exported if
525 the following rules apply:
527 - If it has any non-inline non-pure virtual functions,
528 at least one of these need to be declared dllimport
529 OR any of the constructors is declared dllimport.
533 - The class has an inline constructor/destructor and
534 a key-function (placement of vtable uniquely defined) that
535 is defined in this translation unit.
537 The specification also says that for classes which will have their
538 vtables and rtti exported that their base class(es) might also need a
539 similar exporting if:
541 - Every base class needs to have its vtable & rtti exported
542 as well, if the following the conditions hold true:
543 + The base class has a non-inline declared non-pure virtual function
544 + The base class is polymorphic (has or inherits any virtual functions)
545 or the base class has any virtual base classes. */
547 /* Decide if a base class of a class should
548 also have its vtable and rtti exported. */
551 symbian_possibly_export_base_class (tree base_class)
556 if (! (TYPE_CONTAINS_VPTR_P (base_class)))
559 methods = CLASSTYPE_METHOD_VEC (base_class);
560 len = methods ? TREE_VEC_LENGTH (methods) : 0;
564 tree member = TREE_VEC_ELT (methods, len);
569 for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
571 if (TREE_CODE (member) != FUNCTION_DECL)
574 if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
577 if (! DECL_VIRTUAL_P (member))
580 if (DECL_PURE_VIRTUAL_P (member))
583 if (DECL_INLINE (member))
596 /* FIXME: According to the spec this base class should be exported, but
597 a) how do we do this ? and
598 b) it does not appear to be necessary for compliance with the Symbian
599 OS which so far is the only consumer of this code. */
601 print_node_brief (stderr, "", base_class, 0);
602 fprintf (stderr, " EXPORTed [base class of exported class]\n");
606 /* Decide if a class needs its vtable and rtti exporting. */
609 symbian_export_vtable_and_rtti_p (tree ctype)
611 bool inline_ctor_dtor;
612 bool dllimport_ctor_dtor;
613 bool dllimport_member;
614 tree binfo, base_binfo;
620 /* Make sure that we are examining a class... */
621 if (TREE_CODE (ctype) != RECORD_TYPE)
624 print_node_brief (stderr, "", ctype, 0);
625 fprintf (stderr, " does NOT need to be EXPORTed [not a class]\n");
630 /* If the class does not have a key function it
631 does not need to have its vtable exported. */
632 if ((key = CLASSTYPE_KEY_METHOD (ctype)) == NULL_TREE)
635 print_node_brief (stderr, "", ctype, 0);
636 fprintf (stderr, " does NOT need to be EXPORTed [no key function]\n");
641 /* If the key fn has not been defined
642 then the class should not be exported. */
643 if (! TREE_ASM_WRITTEN (key))
646 print_node_brief (stderr, "", ctype, 0);
647 fprintf (stderr, " does NOT need to be EXPORTed [key function not defined]\n");
652 /* Check the class's member functions. */
653 inline_ctor_dtor = false;
654 dllimport_ctor_dtor = false;
655 dllimport_member = false;
657 methods = CLASSTYPE_METHOD_VEC (ctype);
658 len = methods ? TREE_VEC_LENGTH (methods) : 0;
662 tree member = TREE_VEC_ELT (methods, len);
667 for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
669 if (TREE_CODE (member) != FUNCTION_DECL)
672 if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
674 if (DECL_INLINE (member)
675 /* Ignore C++ backend created inline ctors/dtors. */
676 && ( DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (member)
677 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (member)))
678 inline_ctor_dtor = true;
680 if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
681 dllimport_ctor_dtor = true;
685 if (DECL_PURE_VIRTUAL_P (member))
688 if (! DECL_VIRTUAL_P (member))
691 if (DECL_INLINE (member))
694 if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
695 dllimport_member = true;
700 if (! dllimport_member && ! dllimport_ctor_dtor)
703 print_node_brief (stderr, "", ctype, 0);
705 " does NOT need to be EXPORTed [no non-pure virtuals or ctors/dtors with dllimport]\n");
710 if (! inline_ctor_dtor)
713 print_node_brief (stderr, "", ctype, 0);
715 " does NOT need to be EXPORTed [no inline ctor/dtor]\n");
721 print_node_brief (stderr, "", ctype, 0);
722 fprintf (stderr, " DOES need to be EXPORTed\n");
725 /* Now we must check and possibly export the base classes. */
726 for (i = 0, binfo = TYPE_BINFO (ctype);
727 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
728 symbian_possibly_export_base_class (BINFO_TYPE (base_binfo));
733 /* Add the named attribute to a class and its vtable and rtti. */
736 symbian_add_attribute_to_class_vtable_and_rtti (tree ctype, const char *attr_name)
738 symbian_add_attribute (ctype, attr_name);
740 /* If the vtable exists then they need annotating as well. */
741 if (CLASSTYPE_VTABLES (ctype))
742 /* XXX - Do we need to annotate any vtables other than the primary ? */
743 symbian_add_attribute (CLASSTYPE_VTABLES (ctype), attr_name);
745 /* If the rtti exists then it needs annotating as well. */
746 if (TYPE_MAIN_VARIANT (ctype)
747 && CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))
748 symbian_add_attribute (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)),
752 /* Decide if a class needs to have an attribute because
753 one of its member functions has the attribute. */
756 symbian_class_needs_attribute_p (tree ctype, const char *attribute_name)
758 /* If the key function has the attribute then the class needs it too. */
759 if (TYPE_POLYMORPHIC_P (ctype)
760 && CLASSTYPE_KEY_METHOD (ctype)
761 && lookup_attribute (attribute_name,
762 DECL_ATTRIBUTES (CLASSTYPE_KEY_METHOD (ctype))))
765 /* Check the class's member functions. */
766 if (TREE_CODE (ctype) == RECORD_TYPE)
768 tree methods = CLASSTYPE_METHOD_VEC (ctype);
769 unsigned int len = methods ? TREE_VEC_LENGTH (methods) : 0;
773 tree member = TREE_VEC_ELT (methods, len);
778 for (member = OVL_CURRENT (member);
780 member = OVL_NEXT (member))
782 if (TREE_CODE (member) != FUNCTION_DECL)
785 if (DECL_PURE_VIRTUAL_P (member))
788 if (! DECL_VIRTUAL_P (member))
791 if (lookup_attribute (attribute_name, DECL_ATTRIBUTES (member)))
794 print_node_brief (stderr, "", ctype, 0);
795 fprintf (stderr, " inherits %s because", attribute_name);
796 print_node_brief (stderr, "", member, 0);
797 fprintf (stderr, " has it.\n");
806 print_node_brief (stderr, "", ctype, 0);
807 fprintf (stderr, " does not inherit %s\n", attribute_name);
813 symbian_import_export_class (tree ctype, int import_export)
815 const char *attr_name = NULL;
817 /* If we are exporting the class but it does not have the dllexport
818 attribute then we may need to add it. Similarly imported classes
819 may need the dllimport attribute. */
820 switch (import_export)
822 case 1: attr_name = "dllexport"; break;
823 case -1: attr_name = "dllimport"; break;
828 && ! lookup_attribute (attr_name, TYPE_ATTRIBUTES (ctype)))
830 if (symbian_class_needs_attribute_p (ctype, attr_name))
831 symbian_add_attribute_to_class_vtable_and_rtti (ctype, attr_name);
833 /* Classes can be forced to export their
834 vtable and rtti under certain conditions. */
835 if (symbian_export_vtable_and_rtti_p (ctype))
837 symbian_add_attribute_to_class_vtable_and_rtti (ctype, "dllexport");
839 /* Make sure that the class and its vtable are exported. */
842 if (CLASSTYPE_VTABLES (ctype))
843 DECL_EXTERNAL (CLASSTYPE_VTABLES (ctype)) = 1;
845 /* Check to make sure that if the class has a key method that
846 it is now on the list of keyed classes. That way its vtable
848 if (CLASSTYPE_KEY_METHOD (ctype))
852 for (class = keyed_classes; class; class = TREE_CHAIN (class))
856 if (class == NULL_TREE)
859 print_node_brief (stderr, "Add node", ctype, 0);
860 fprintf (stderr, " to the keyed classes list\n");
862 keyed_classes = tree_cons (NULL_TREE, ctype, keyed_classes);
866 /* Make sure that the typeinfo will be emitted as well. */
867 if (CLASS_TYPE_P (ctype))
868 TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))) = 1;
872 return import_export;
875 /* Dummy definition of this array for cc1 building purposes. */
876 tree cp_global_trees[CPTI_MAX] __attribute__((weak));
878 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
880 /* Dummy version of this G++ function for building cc1. */
881 void lang_check_failed (const char *, int, const char *) __attribute__((weak));
884 lang_check_failed (const char *file, int line, const char *function)
886 internal_error ("lang_* check: failed in %s, at %s:%d",
887 function, trim_filename (file), line);
889 #endif /* ENABLE_TREE_CHECKING */