00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "rtl.h"
00028 #include "output.h"
00029 #include "flags.h"
00030 #include "tree.h"
00031 #include "expr.h"
00032 #include "tm_p.h"
00033 #include "cp/cp-tree.h"
00034 #include "toplev.h"
00035
00036
00037
00038
00039
00040 #define SYMBIAN_DEBUG 0
00041
00042
00043
00044
00045 #define SH_SYMBIAN_FLAG_CHAR "$"
00046
00047
00048 #define DLL_IMPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "i."
00049 #define DLL_EXPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "e."
00050
00051
00052
00053
00054
00055 static tree
00056 sh_symbian_associated_type (tree decl)
00057 {
00058 tree t = NULL_TREE;
00059
00060 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
00061
00062
00063
00064
00065 return t;
00066
00067
00068 if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
00069 t = DECL_CONTEXT (decl);
00070
00071 return t;
00072 }
00073
00074
00075
00076 bool
00077 sh_symbian_dllexport_p (tree decl)
00078 {
00079 tree exp;
00080
00081 if ( TREE_CODE (decl) != VAR_DECL
00082 && TREE_CODE (decl) != FUNCTION_DECL)
00083 return false;
00084
00085 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
00086
00087
00088 if (exp == NULL)
00089 {
00090 tree class = sh_symbian_associated_type (decl);
00091
00092 if (class)
00093 exp = lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class));
00094 }
00095 #if SYMBIAN_DEBUG
00096 if (exp)
00097 {
00098 print_node_brief (stderr, "dllexport:", decl, 0);
00099 fprintf (stderr, "\n");
00100 }
00101 else
00102 #if SYMBIAN_DEBUG < 2
00103 if (TREE_CODE (decl) != FUNCTION_DECL)
00104 #endif
00105 {
00106 print_node_brief (stderr, "no dllexport:", decl, 0);
00107 fprintf (stderr, "\n");
00108 }
00109 #endif
00110 return exp ? true : false;
00111 }
00112
00113
00114
00115 static bool
00116 sh_symbian_dllimport_p (tree decl)
00117 {
00118 tree imp;
00119
00120 if ( TREE_CODE (decl) != VAR_DECL
00121 && TREE_CODE (decl) != FUNCTION_DECL)
00122 return false;
00123
00124 imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
00125 if (imp)
00126 return true;
00127
00128
00129 imp = sh_symbian_associated_type (decl);
00130 if (! imp)
00131 return false;
00132
00133 imp = lookup_attribute ("dllimport", TYPE_ATTRIBUTES (imp));
00134 if (!imp)
00135 return false;
00136
00137
00138
00139
00140
00141 if (TREE_CODE (decl) == FUNCTION_DECL
00142 && DECL_INITIAL (decl)
00143 && !DECL_INLINE (decl))
00144 {
00145
00146 if (!DECL_ARTIFICIAL (decl))
00147 warning ("%H function '%D' is defined after prior declaration as dllimport: attribute ignored",
00148 & DECL_SOURCE_LOCATION (decl), decl);
00149 return false;
00150 }
00151
00152
00153
00154
00155 else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
00156 {
00157 if (extra_warnings)
00158 warning ("%Hinline function '%D' is declared as dllimport: attribute ignored.",
00159 & DECL_SOURCE_LOCATION (decl), decl);
00160 return false;
00161 }
00162
00163
00164
00165 else if (TREE_CODE (decl) == VAR_DECL
00166 && TREE_STATIC (decl)
00167 && TREE_PUBLIC (decl)
00168 && !DECL_EXTERNAL (decl))
00169 {
00170 if (!DECL_VIRTUAL_P (decl))
00171 error ("%Hdefinition of static data member '%D' of dllimport'd class.",
00172 & DECL_SOURCE_LOCATION (decl), decl);
00173 return false;
00174 }
00175
00176
00177
00178
00179
00180
00181 else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
00182 && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
00183 return false;
00184
00185 return true;
00186 }
00187
00188
00189
00190 bool
00191 sh_symbian_dllexport_name_p (const char *symbol)
00192 {
00193 return strncmp (DLL_EXPORT_PREFIX, symbol,
00194 strlen (DLL_EXPORT_PREFIX)) == 0;
00195 }
00196
00197
00198
00199
00200 bool
00201 sh_symbian_dllimport_name_p (const char *symbol)
00202 {
00203 return strncmp (DLL_IMPORT_PREFIX, symbol,
00204 strlen (DLL_IMPORT_PREFIX)) == 0;
00205 }
00206
00207
00208
00209
00210 static void
00211 sh_symbian_mark_dllexport (tree decl)
00212 {
00213 const char *oldname;
00214 char *newname;
00215 rtx rtlname;
00216 tree idp;
00217
00218 rtlname = XEXP (DECL_RTL (decl), 0);
00219
00220 if (GET_CODE (rtlname) == SYMBOL_REF)
00221 oldname = XSTR (rtlname, 0);
00222 else if (GET_CODE (rtlname) == MEM
00223 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
00224 oldname = XSTR (XEXP (rtlname, 0), 0);
00225 else
00226 abort ();
00227
00228 if (sh_symbian_dllimport_name_p (oldname))
00229 {
00230
00231
00232
00233
00234
00235
00236
00237 oldname += strlen (DLL_IMPORT_PREFIX);
00238 DECL_NON_ADDR_CONST_P (decl) = 0;
00239 }
00240 else if (sh_symbian_dllexport_name_p (oldname))
00241 return;
00242
00243 newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
00244 sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
00245
00246
00247
00248
00249
00250 idp = get_identifier (newname);
00251
00252 XEXP (DECL_RTL (decl), 0) =
00253 gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
00254 }
00255
00256
00257
00258 static void
00259 sh_symbian_mark_dllimport (tree decl)
00260 {
00261 const char *oldname;
00262 char *newname;
00263 tree idp;
00264 rtx rtlname;
00265 rtx newrtl;
00266
00267 rtlname = XEXP (DECL_RTL (decl), 0);
00268
00269 if (GET_CODE (rtlname) == SYMBOL_REF)
00270 oldname = XSTR (rtlname, 0);
00271 else if (GET_CODE (rtlname) == MEM
00272 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
00273 oldname = XSTR (XEXP (rtlname, 0), 0);
00274 else
00275 abort ();
00276
00277 if (sh_symbian_dllexport_name_p (oldname))
00278 {
00279 error ("%qs declared as both exported to and imported from a DLL",
00280 IDENTIFIER_POINTER (DECL_NAME (decl)));
00281 }
00282 else if (sh_symbian_dllimport_name_p (oldname))
00283 {
00284
00285 if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
00286 error ("%Hfailure in redeclaration of '%D': dllimport'd symbol lacks external linkage.",
00287 &DECL_SOURCE_LOCATION (decl), decl);
00288 }
00289 else
00290 {
00291 newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
00292 sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
00293
00294
00295
00296
00297
00298 idp = get_identifier (newname);
00299 newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
00300 XEXP (DECL_RTL (decl), 0) = newrtl;
00301 }
00302 }
00303
00304 void
00305 sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
00306 {
00307 default_encode_section_info (decl, rtl, first);
00308
00309
00310
00311 if (sh_symbian_dllexport_p (decl))
00312 sh_symbian_mark_dllexport (decl);
00313 else if (sh_symbian_dllimport_p (decl))
00314 sh_symbian_mark_dllimport (decl);
00315
00316
00317
00318
00319 else if ( (TREE_CODE (decl) == FUNCTION_DECL
00320 || TREE_CODE (decl) == VAR_DECL)
00321 && DECL_RTL (decl) != NULL_RTX
00322 && GET_CODE (DECL_RTL (decl)) == MEM
00323 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
00324 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
00325 && sh_symbian_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
00326 {
00327 const char * oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
00328
00329 tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
00330 rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
00331
00332 warning ("%H%s '%D' %s after being referenced with dllimport linkage.",
00333 & DECL_SOURCE_LOCATION (decl),
00334 TREE_CODE (decl) == VAR_DECL ? "variable" : "function",
00335 decl, (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
00336 ? "defined locally" : "redeclared without dllimport attribute");
00337
00338 XEXP (DECL_RTL (decl), 0) = newrtl;
00339
00340 DECL_NON_ADDR_CONST_P (decl) = 0;
00341 }
00342 }
00343
00344
00345
00346
00347
00348 static int
00349 sh_symbian_get_strip_length (int c)
00350 {
00351
00352 return (c == SH_SYMBIAN_FLAG_CHAR[0]) ? strlen (DLL_EXPORT_PREFIX) : 0;
00353 }
00354
00355
00356
00357
00358 const char *
00359 sh_symbian_strip_name_encoding (const char *name)
00360 {
00361 int skip;
00362
00363 while ((skip = sh_symbian_get_strip_length (*name)))
00364 name += skip;
00365
00366 return name;
00367 }
00368
00369
00370
00371
00372 static void
00373 symbian_add_attribute (tree node, const char *attr_name)
00374 {
00375 tree attrs;
00376 tree attr;
00377
00378 attrs = DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node);
00379
00380 if (lookup_attribute (attr_name, attrs) != NULL_TREE)
00381 return;
00382
00383 attr = get_identifier (attr_name);
00384
00385 (DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node))
00386 = tree_cons (attr, NULL_TREE, attrs);
00387
00388 #if SYMBIAN_DEBUG
00389 fprintf (stderr, "propogate %s attribute", attr_name);
00390 print_node_brief (stderr, " to", node, 0);
00391 fprintf (stderr, "\n");
00392 #endif
00393 }
00394
00395
00396
00397
00398 tree
00399 sh_symbian_handle_dll_attribute (tree *pnode, tree name, tree args,
00400 int flags, bool *no_add_attrs)
00401 {
00402 tree thunk;
00403 tree node = *pnode;
00404 const char *attr = IDENTIFIER_POINTER (name);
00405
00406
00407
00408 if (!DECL_P (node))
00409 {
00410 if (flags & ((int) ATTR_FLAG_DECL_NEXT
00411 | (int) ATTR_FLAG_FUNCTION_NEXT
00412 | (int) ATTR_FLAG_ARRAY_NEXT))
00413 {
00414 warning ("%qs attribute ignored", attr);
00415 *no_add_attrs = true;
00416 return tree_cons (name, args, NULL_TREE);
00417 }
00418
00419 if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
00420 {
00421 warning ("%qs attribute ignored", attr);
00422 *no_add_attrs = true;
00423 }
00424
00425 return NULL_TREE;
00426 }
00427
00428
00429
00430 else if (is_attribute_p ("dllimport", name))
00431 {
00432 if (TREE_CODE (node) == VAR_DECL)
00433 {
00434 if (DECL_INITIAL (node))
00435 {
00436 error ("%Hvariable %qD definition is marked dllimport.",
00437 & DECL_SOURCE_LOCATION (node), node);
00438 *no_add_attrs = true;
00439 }
00440
00441
00442
00443 DECL_EXTERNAL (node) = 1;
00444
00445
00446 if (current_function_decl != NULL_TREE && ! TREE_STATIC (node))
00447 TREE_PUBLIC (node) = 1;
00448 }
00449 }
00450
00451
00452
00453
00454
00455 if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE
00456 && (DECL_CONSTRUCTOR_P (node) || DECL_DESTRUCTOR_P (node)))
00457 {
00458 tree overload;
00459
00460 for (overload = OVL_CHAIN (node); overload; overload = OVL_CHAIN (overload))
00461 {
00462 tree node_args;
00463 tree func_args;
00464 tree function = OVL_CURRENT (overload);
00465
00466 if (! function
00467 || ! DECL_P (function)
00468 || (DECL_CONSTRUCTOR_P (node) && ! DECL_CONSTRUCTOR_P (function))
00469 || (DECL_DESTRUCTOR_P (node) && ! DECL_DESTRUCTOR_P (function)))
00470 continue;
00471
00472
00473 for (node_args = DECL_ARGUMENTS (node), func_args = DECL_ARGUMENTS (function);
00474 node_args && func_args;
00475 node_args = TREE_CHAIN (node_args), func_args = TREE_CHAIN (func_args))
00476 if (TREE_TYPE (node_args) != TREE_TYPE (func_args))
00477 break;
00478
00479 if (node_args || func_args)
00480 {
00481
00482
00483 if ((node_args == NULL_TREE
00484 || func_args != NULL_TREE)
00485 && strcmp (IDENTIFIER_POINTER (DECL_NAME (node)), "__in_chrg") != 0)
00486 continue;
00487 }
00488
00489 symbian_add_attribute (function, attr);
00490
00491
00492 for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
00493 if (TREE_CODE (thunk) == FUNCTION_DECL)
00494 symbian_add_attribute (thunk, attr);
00495 }
00496 }
00497
00498 if (TREE_CODE (node) == FUNCTION_DECL && DECL_VIRTUAL_P (node))
00499 {
00500
00501 for (thunk = DECL_THUNKS (node); thunk; thunk = TREE_CHAIN (thunk))
00502 if (TREE_CODE (thunk) == FUNCTION_DECL)
00503 symbian_add_attribute (thunk, attr);
00504 }
00505
00506
00507 if (!TREE_PUBLIC (node)
00508 && ( TREE_CODE (node) == VAR_DECL
00509 || TREE_CODE (node) == FUNCTION_DECL))
00510 {
00511 error ("%Hexternal linkage required for symbol '%D' because of '%s' attribute.",
00512 & DECL_SOURCE_LOCATION (node), node, IDENTIFIER_POINTER (name));
00513 *no_add_attrs = true;
00514 }
00515
00516 #if SYMBIAN_DEBUG
00517 print_node_brief (stderr, "mark node", node, 0);
00518 fprintf (stderr, " as %s\n", attr);
00519 #endif
00520
00521 return NULL_TREE;
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 static void
00557 symbian_possibly_export_base_class (tree base_class)
00558 {
00559 tree methods;
00560 int len;
00561
00562 if (! (TYPE_CONTAINS_VPTR_P (base_class)))
00563 return;
00564
00565 methods = CLASSTYPE_METHOD_VEC (base_class);
00566 len = methods ? TREE_VEC_LENGTH (methods) : 0;
00567
00568 for (;len --;)
00569 {
00570 tree member = TREE_VEC_ELT (methods, len);
00571
00572 if (! member)
00573 continue;
00574
00575 for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
00576 {
00577 if (TREE_CODE (member) != FUNCTION_DECL)
00578 continue;
00579
00580 if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
00581 continue;
00582
00583 if (! DECL_VIRTUAL_P (member))
00584 continue;
00585
00586 if (DECL_PURE_VIRTUAL_P (member))
00587 continue;
00588
00589 if (DECL_INLINE (member))
00590 continue;
00591
00592 break;
00593 }
00594
00595 if (member)
00596 break;
00597 }
00598
00599 if (len < 0)
00600 return;
00601
00602
00603
00604
00605
00606 #if SYMBIAN_DEBUG
00607 print_node_brief (stderr, "", base_class, 0);
00608 fprintf (stderr, " EXPORTed [base class of exported class]\n");
00609 #endif
00610 }
00611
00612
00613
00614 static bool
00615 symbian_export_vtable_and_rtti_p (tree ctype)
00616 {
00617 bool inline_ctor_dtor;
00618 bool dllimport_ctor_dtor;
00619 bool dllimport_member;
00620 tree binfo, base_binfo;
00621 tree methods;
00622 tree key;
00623 int i;
00624 int len;
00625
00626
00627 if (TREE_CODE (ctype) != RECORD_TYPE)
00628 {
00629 #if SYMBIAN_DEBUG
00630 print_node_brief (stderr, "", ctype, 0);
00631 fprintf (stderr, " does NOT need to be EXPORTed [not a class]\n");
00632 #endif
00633 return false;
00634 }
00635
00636
00637
00638 if ((key = CLASSTYPE_KEY_METHOD (ctype)) == NULL_TREE)
00639 {
00640 #if SYMBIAN_DEBUG
00641 print_node_brief (stderr, "", ctype, 0);
00642 fprintf (stderr, " does NOT need to be EXPORTed [no key function]\n");
00643 #endif
00644 return false;
00645 }
00646
00647
00648
00649 if (! TREE_ASM_WRITTEN (key))
00650 {
00651 #if SYMBIAN_DEBUG
00652 print_node_brief (stderr, "", ctype, 0);
00653 fprintf (stderr, " does NOT need to be EXPORTed [key function not defined]\n");
00654 #endif
00655 return false;
00656 }
00657
00658
00659 inline_ctor_dtor = false;
00660 dllimport_ctor_dtor = false;
00661 dllimport_member = false;
00662
00663 methods = CLASSTYPE_METHOD_VEC (ctype);
00664 len = methods ? TREE_VEC_LENGTH (methods) : 0;
00665
00666 for (;len --;)
00667 {
00668 tree member = TREE_VEC_ELT (methods, len);
00669
00670 if (! member)
00671 continue;
00672
00673 for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
00674 {
00675 if (TREE_CODE (member) != FUNCTION_DECL)
00676 continue;
00677
00678 if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
00679 {
00680 if (DECL_INLINE (member)
00681
00682 && ( DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (member)
00683 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (member)))
00684 inline_ctor_dtor = true;
00685
00686 if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
00687 dllimport_ctor_dtor = true;
00688 }
00689 else
00690 {
00691 if (DECL_PURE_VIRTUAL_P (member))
00692 continue;
00693
00694 if (! DECL_VIRTUAL_P (member))
00695 continue;
00696
00697 if (DECL_INLINE (member))
00698 continue;
00699
00700 if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
00701 dllimport_member = true;
00702 }
00703 }
00704 }
00705
00706 if (! dllimport_member && ! dllimport_ctor_dtor)
00707 {
00708 #if SYMBIAN_DEBUG
00709 print_node_brief (stderr, "", ctype, 0);
00710 fprintf (stderr,
00711 " does NOT need to be EXPORTed [no non-pure virtuals or ctors/dtors with dllimport]\n");
00712 #endif
00713 return false;
00714 }
00715
00716 if (! inline_ctor_dtor)
00717 {
00718 #if SYMBIAN_DEBUG
00719 print_node_brief (stderr, "", ctype, 0);
00720 fprintf (stderr,
00721 " does NOT need to be EXPORTed [no inline ctor/dtor]\n");
00722 #endif
00723 return false;
00724 }
00725
00726 #if SYMBIAN_DEBUG
00727 print_node_brief (stderr, "", ctype, 0);
00728 fprintf (stderr, " DOES need to be EXPORTed\n");
00729 #endif
00730
00731
00732 for (i = 0, binfo = TYPE_BINFO (ctype);
00733 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
00734 symbian_possibly_export_base_class (BINFO_TYPE (base_binfo));
00735
00736 return true;
00737 }
00738
00739
00740
00741 static void
00742 symbian_add_attribute_to_class_vtable_and_rtti (tree ctype, const char *attr_name)
00743 {
00744 symbian_add_attribute (ctype, attr_name);
00745
00746
00747 if (CLASSTYPE_VTABLES (ctype))
00748
00749 symbian_add_attribute (CLASSTYPE_VTABLES (ctype), attr_name);
00750
00751
00752 if (TYPE_MAIN_VARIANT (ctype)
00753 && CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))
00754 symbian_add_attribute (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)),
00755 attr_name);
00756 }
00757
00758
00759
00760
00761 static bool
00762 symbian_class_needs_attribute_p (tree ctype, const char *attribute_name)
00763 {
00764
00765 if (TYPE_POLYMORPHIC_P (ctype)
00766 && CLASSTYPE_KEY_METHOD (ctype)
00767 && lookup_attribute (attribute_name,
00768 DECL_ATTRIBUTES (CLASSTYPE_KEY_METHOD (ctype))))
00769 return true;
00770
00771
00772 if (TREE_CODE (ctype) == RECORD_TYPE)
00773 {
00774 tree methods = CLASSTYPE_METHOD_VEC (ctype);
00775 unsigned int len = methods ? TREE_VEC_LENGTH (methods) : 0;
00776
00777 for (;len --;)
00778 {
00779 tree member = TREE_VEC_ELT (methods, len);
00780
00781 if (! member)
00782 continue;
00783
00784 for (member = OVL_CURRENT (member);
00785 member;
00786 member = OVL_NEXT (member))
00787 {
00788 if (TREE_CODE (member) != FUNCTION_DECL)
00789 continue;
00790
00791 if (DECL_PURE_VIRTUAL_P (member))
00792 continue;
00793
00794 if (! DECL_VIRTUAL_P (member))
00795 continue;
00796
00797 if (lookup_attribute (attribute_name, DECL_ATTRIBUTES (member)))
00798 {
00799 #if SYMBIAN_DEBUG
00800 print_node_brief (stderr, "", ctype, 0);
00801 fprintf (stderr, " inherits %s because", attribute_name);
00802 print_node_brief (stderr, "", member, 0);
00803 fprintf (stderr, " has it.\n");
00804 #endif
00805 return true;
00806 }
00807 }
00808 }
00809 }
00810
00811 #if SYMBIAN_DEBUG
00812 print_node_brief (stderr, "", ctype, 0);
00813 fprintf (stderr, " does not inherit %s\n", attribute_name);
00814 #endif
00815 return false;
00816 }
00817
00818 int
00819 symbian_import_export_class (tree ctype, int import_export)
00820 {
00821 const char *attr_name = NULL;
00822
00823
00824
00825
00826 switch (import_export)
00827 {
00828 case 1: attr_name = "dllexport"; break;
00829 case -1: attr_name = "dllimport"; break;
00830 default: break;
00831 }
00832
00833 if (attr_name
00834 && ! lookup_attribute (attr_name, TYPE_ATTRIBUTES (ctype)))
00835 {
00836 if (symbian_class_needs_attribute_p (ctype, attr_name))
00837 symbian_add_attribute_to_class_vtable_and_rtti (ctype, attr_name);
00838
00839
00840
00841 if (symbian_export_vtable_and_rtti_p (ctype))
00842 {
00843 symbian_add_attribute_to_class_vtable_and_rtti (ctype, "dllexport");
00844
00845
00846 import_export = 1;
00847
00848 if (CLASSTYPE_VTABLES (ctype))
00849 DECL_EXTERNAL (CLASSTYPE_VTABLES (ctype)) = 1;
00850
00851
00852
00853
00854 if (CLASSTYPE_KEY_METHOD (ctype))
00855 {
00856 tree class;
00857
00858 for (class = keyed_classes; class; class = TREE_CHAIN (class))
00859 if (class == ctype)
00860 break;
00861
00862 if (class == NULL_TREE)
00863 {
00864 #if SYMBIAN_DEBUG
00865 print_node_brief (stderr, "Add node", ctype, 0);
00866 fprintf (stderr, " to the keyed classes list\n");
00867 #endif
00868 keyed_classes = tree_cons (NULL_TREE, ctype, keyed_classes);
00869 }
00870 }
00871
00872
00873 if (CLASS_TYPE_P (ctype))
00874 TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))) = 1;
00875 }
00876 }
00877
00878 return import_export;
00879 }
00880
00881
00882 tree cp_global_trees[CPTI_MAX] __attribute__((weak));
00883
00884 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
00885
00886
00887 void lang_check_failed (const char *, int, const char *) __attribute__((weak));
00888
00889 void
00890 lang_check_failed (const char *file, int line, const char *function)
00891 {
00892 internal_error ("lang_* check: failed in %s, at %s:%d",
00893 function, trim_filename (file), line);
00894 }
00895 #endif