150397Sobrien/* RunTime Type Identification 2169689Skan Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 3169689Skan 2005, 2006 490075Sobrien Free Software Foundation, Inc. 550397Sobrien Mostly written by Jason Merrill (jason@cygnus.com). 650397Sobrien 7132718SkanThis file is part of GCC. 850397Sobrien 9132718SkanGCC is free software; you can redistribute it and/or modify 1050397Sobrienit under the terms of the GNU General Public License as published by 1150397Sobrienthe Free Software Foundation; either version 2, or (at your option) 1250397Sobrienany later version. 1350397Sobrien 14132718SkanGCC is distributed in the hope that it will be useful, 1550397Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1650397SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1750397SobrienGNU General Public License for more details. 1850397Sobrien 1950397SobrienYou should have received a copy of the GNU General Public License 20132718Skanalong with GCC; see the file COPYING. If not, write to 21169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 22169689SkanBoston, MA 02110-1301, USA. */ 2350397Sobrien 2450397Sobrien#include "config.h" 2550397Sobrien#include "system.h" 26132718Skan#include "coretypes.h" 27132718Skan#include "tm.h" 2850397Sobrien#include "tree.h" 2950397Sobrien#include "cp-tree.h" 3050397Sobrien#include "flags.h" 3150397Sobrien#include "output.h" 3250397Sobrien#include "assert.h" 3350397Sobrien#include "toplev.h" 34132718Skan#include "convert.h" 35259649Spfg#include "target.h" 3650397Sobrien 37102780Skan/* C++ returns type information to the user in struct type_info 38102780Skan objects. We also use type information to implement dynamic_cast and 39102780Skan exception handlers. Type information for a particular type is 40102780Skan indicated with an ABI defined structure derived from type_info. 41102780Skan This would all be very straight forward, but for the fact that the 42102780Skan runtime library provides the definitions of the type_info structure 43102780Skan and the ABI defined derived classes. We cannot build declarations 44102780Skan of them directly in the compiler, but we need to layout objects of 45102780Skan their type. Somewhere we have to lie. 46102780Skan 47102780Skan We define layout compatible POD-structs with compiler-defined names 48102780Skan and generate the appropriate initializations for them (complete 49102780Skan with explicit mention of their vtable). When we have to provide a 50102780Skan type_info to the user we reinterpret_cast the internal compiler 51102780Skan type to type_info. A well formed program can only explicitly refer 52102780Skan to the type_infos of complete types (& cv void). However, we chain 53102780Skan pointer type_infos to the pointed-to-type, and that can be 54102780Skan incomplete. We only need the addresses of such incomplete 55102780Skan type_info objects for static initialization. 56102780Skan 57102780Skan The type information VAR_DECL of a type is held on the 58102780Skan IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL 59102780Skan will be the internal type. It will usually have the correct 60102780Skan internal type reflecting the kind of type it represents (pointer, 61102780Skan array, function, class, inherited class, etc). When the type it 62102780Skan represents is incomplete, it will have the internal type 63102780Skan corresponding to type_info. That will only happen at the end of 64102780Skan translation, when we are emitting the type info objects. */ 65102780Skan 66169689Skan/* Auxiliary data we hold for each type_info derived object we need. */ 67169689Skantypedef struct tinfo_s GTY (()) 68169689Skan{ 69169689Skan tree type; /* The RECORD_TYPE for this type_info object */ 7050397Sobrien 71169689Skan tree vtable; /* The VAR_DECL of the vtable. Only filled at end of 72169689Skan translation. */ 7350397Sobrien 74169689Skan tree name; /* IDENTIFIER_NODE for the ABI specified name of 75169689Skan the type_info derived type. */ 76169689Skan} tinfo_s; 77169689Skan 78169689SkanDEF_VEC_O(tinfo_s); 79169689SkanDEF_VEC_ALLOC_O(tinfo_s,gc); 80169689Skan 81169689Skantypedef enum tinfo_kind 82169689Skan{ 83169689Skan TK_TYPE_INFO_TYPE, /* std::type_info */ 84169689Skan TK_BASE_TYPE, /* abi::__base_class_type_info */ 85169689Skan TK_BUILTIN_TYPE, /* abi::__fundamental_type_info */ 86169689Skan TK_ARRAY_TYPE, /* abi::__array_type_info */ 87169689Skan TK_FUNCTION_TYPE, /* abi::__function_type_info */ 88169689Skan TK_ENUMERAL_TYPE, /* abi::__enum_type_info */ 89169689Skan TK_POINTER_TYPE, /* abi::__pointer_type_info */ 90169689Skan TK_POINTER_MEMBER_TYPE, /* abi::__pointer_to_member_type_info */ 91169689Skan TK_CLASS_TYPE, /* abi::__class_type_info */ 92169689Skan TK_SI_CLASS_TYPE, /* abi::__si_class_type_info */ 93169689Skan TK_FIXED /* end of fixed descriptors. */ 94169689Skan /* ... abi::__vmi_type_info<I> */ 95169689Skan} tinfo_kind; 96169689Skan 97169689Skan/* A vector of all tinfo decls that haven't yet been emitted. */ 98169689SkanVEC(tree,gc) *unemitted_tinfo_decls; 99169689Skan 100169689Skan/* A vector of all type_info derived types we need. The first few are 101169689Skan fixed and created early. The remainder are for multiple inheritance 102169689Skan and are generated as needed. */ 103169689Skanstatic GTY (()) VEC(tinfo_s,gc) *tinfo_descs; 104169689Skan 105132718Skanstatic tree build_headof (tree); 106132718Skanstatic tree ifnonnull (tree, tree); 107132718Skanstatic tree tinfo_name (tree); 108132718Skanstatic tree build_dynamic_cast_1 (tree, tree); 109132718Skanstatic tree throw_bad_cast (void); 110132718Skanstatic tree throw_bad_typeid (void); 111132718Skanstatic tree get_tinfo_decl_dynamic (tree); 112132718Skanstatic tree get_tinfo_ptr (tree); 113132718Skanstatic bool typeid_ok_p (void); 114132718Skanstatic int qualifier_flags (tree); 115132718Skanstatic bool target_incomplete_p (tree); 116169689Skanstatic tree tinfo_base_init (tinfo_s *, tree); 117169689Skanstatic tree generic_initializer (tinfo_s *, tree); 118169689Skanstatic tree ptr_initializer (tinfo_s *, tree); 119169689Skanstatic tree ptm_initializer (tinfo_s *, tree); 120169689Skanstatic tree class_initializer (tinfo_s *, tree, tree); 121169689Skanstatic void create_pseudo_type_info (int, const char *, ...); 122169689Skanstatic tree get_pseudo_ti_init (tree, unsigned); 123169689Skanstatic unsigned get_pseudo_ti_index (tree); 124132718Skanstatic void create_tinfo_types (void); 125132718Skanstatic bool typeinfo_in_lib_p (tree); 126132718Skan 12790075Sobrienstatic int doing_runtime = 0; 12850397Sobrien 129102780Skan 130102780Skan/* Declare language defined type_info type and a pointer to const 131102780Skan type_info. This is incomplete here, and will be completed when 132102780Skan the user #includes <typeinfo>. There are language defined 133102780Skan restrictions on what can be done until that is included. Create 134102780Skan the internal versions of the ABI types. */ 135102780Skan 13650397Sobrienvoid 137132718Skaninit_rtti_processing (void) 13850397Sobrien{ 139169689Skan tree type_info_type; 140132718Skan 14190075Sobrien push_namespace (std_identifier); 142169689Skan type_info_type = xref_tag (class_type, get_identifier ("type_info"), 143169689Skan /*tag_scope=*/ts_current, false); 14490075Sobrien pop_namespace (); 145169689Skan const_type_info_type_node 146169689Skan = build_qualified_type (type_info_type, TYPE_QUAL_CONST); 147169689Skan type_info_ptr_type = build_pointer_type (const_type_info_type_node); 148102780Skan 149169689Skan unemitted_tinfo_decls = VEC_alloc (tree, gc, 124); 150132718Skan 151102780Skan create_tinfo_types (); 15250397Sobrien} 15350397Sobrien 15450397Sobrien/* Given the expression EXP of type `class *', return the head of the 15550397Sobrien object pointed to by EXP with type cv void*, if the class has any 15690075Sobrien virtual functions (TYPE_POLYMORPHIC_P), else just return the 15750397Sobrien expression. */ 15850397Sobrien 15950397Sobrienstatic tree 160132718Skanbuild_headof (tree exp) 16150397Sobrien{ 16250397Sobrien tree type = TREE_TYPE (exp); 16350397Sobrien tree offset; 16490075Sobrien tree index; 16550397Sobrien 166169689Skan gcc_assert (TREE_CODE (type) == POINTER_TYPE); 16750397Sobrien type = TREE_TYPE (type); 16850397Sobrien 16990075Sobrien if (!TYPE_POLYMORPHIC_P (type)) 17050397Sobrien return exp; 17150397Sobrien 17250397Sobrien /* We use this a couple of times below, protect it. */ 17350397Sobrien exp = save_expr (exp); 17450397Sobrien 17590075Sobrien /* The offset-to-top field is at index -2 from the vptr. */ 176169689Skan index = build_int_cst (NULL_TREE, 177169689Skan -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE); 17850397Sobrien 17990075Sobrien offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index); 18050397Sobrien 181169689Skan type = build_qualified_type (ptr_type_node, 18290075Sobrien cp_type_quals (TREE_TYPE (exp))); 183169689Skan return build2 (PLUS_EXPR, type, exp, 184169689Skan convert_to_integer (ptrdiff_type_node, offset)); 18550397Sobrien} 18650397Sobrien 18750397Sobrien/* Get a bad_cast node for the program to throw... 18850397Sobrien 18950397Sobrien See libstdc++/exception.cc for __throw_bad_cast */ 19050397Sobrien 19150397Sobrienstatic tree 192132718Skanthrow_bad_cast (void) 19350397Sobrien{ 19490075Sobrien tree fn = get_identifier ("__cxa_bad_cast"); 195132718Skan if (!get_global_value_if_present (fn, &fn)) 19690075Sobrien fn = push_throw_library_fn (fn, build_function_type (ptr_type_node, 19790075Sobrien void_list_node)); 198169689Skan 199169689Skan return build_cxx_call (fn, NULL_TREE); 20050397Sobrien} 20150397Sobrien 202132718Skan/* Return an expression for "__cxa_bad_typeid()". The expression 203132718Skan returned is an lvalue of type "const std::type_info". */ 204132718Skan 20550397Sobrienstatic tree 206132718Skanthrow_bad_typeid (void) 20750397Sobrien{ 20890075Sobrien tree fn = get_identifier ("__cxa_bad_typeid"); 209132718Skan if (!get_global_value_if_present (fn, &fn)) 21090075Sobrien { 211169689Skan tree t; 212169689Skan 213169689Skan t = build_reference_type (const_type_info_type_node); 214169689Skan t = build_function_type (t, void_list_node); 21590075Sobrien fn = push_throw_library_fn (fn, t); 21690075Sobrien } 21790075Sobrien 218169689Skan return build_cxx_call (fn, NULL_TREE); 21950397Sobrien} 22050397Sobrien 221132718Skan/* Return an lvalue expression whose type is "const std::type_info" 222132718Skan and whose value indicates the type of the expression EXP. If EXP 223132718Skan is a reference to a polymorphic class, return the dynamic type; 22450397Sobrien otherwise return the static type of the expression. */ 22550397Sobrien 22690075Sobrienstatic tree 227132718Skanget_tinfo_decl_dynamic (tree exp) 22850397Sobrien{ 22950397Sobrien tree type; 230132718Skan tree t; 231169689Skan 232169689Skan if (error_operand_p (exp)) 23350397Sobrien return error_mark_node; 23450397Sobrien 23550397Sobrien /* peel back references, so they match. */ 236132718Skan type = non_reference (TREE_TYPE (exp)); 23750397Sobrien 23850397Sobrien /* Peel off cv qualifiers. */ 23950397Sobrien type = TYPE_MAIN_VARIANT (type); 240169689Skan 241259655Spfg if (CLASS_TYPE_P (type)) 24290075Sobrien type = complete_type_or_else (type, exp); 243169689Skan 24490075Sobrien if (!type) 24590075Sobrien return error_mark_node; 24650397Sobrien 24750397Sobrien /* If exp is a reference to polymorphic type, get the real type_info. */ 24890075Sobrien if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0)) 24950397Sobrien { 25050397Sobrien /* build reference to type_info from vtable. */ 25190075Sobrien tree index; 25250397Sobrien 25390075Sobrien /* The RTTI information is at index -1. */ 254169689Skan index = build_int_cst (NULL_TREE, 255169689Skan -1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE); 25690075Sobrien t = build_vtbl_ref (exp, index); 257169689Skan t = convert (type_info_ptr_type, t); 25850397Sobrien } 259132718Skan else 260132718Skan /* Otherwise return the type_info for the static type of the expr. */ 261132718Skan t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type)); 26250397Sobrien 263132718Skan return build_indirect_ref (t, NULL); 26450397Sobrien} 26550397Sobrien 26690075Sobrienstatic bool 267132718Skantypeid_ok_p (void) 26850397Sobrien{ 26952284Sobrien if (! flag_rtti) 27052284Sobrien { 27152284Sobrien error ("cannot use typeid with -fno-rtti"); 27290075Sobrien return false; 27352284Sobrien } 274169689Skan 275169689Skan if (!COMPLETE_TYPE_P (const_type_info_type_node)) 27652284Sobrien { 27752284Sobrien error ("must #include <typeinfo> before using typeid"); 27890075Sobrien return false; 27952284Sobrien } 280169689Skan 28190075Sobrien return true; 28290075Sobrien} 28390075Sobrien 284132718Skan/* Return an expression for "typeid(EXP)". The expression returned is 285132718Skan an lvalue of type "const std::type_info". */ 286132718Skan 28790075Sobrientree 288132718Skanbuild_typeid (tree exp) 28990075Sobrien{ 29090075Sobrien tree cond = NULL_TREE; 29190075Sobrien int nonnull = 0; 29290075Sobrien 29390075Sobrien if (exp == error_mark_node || !typeid_ok_p ()) 29490075Sobrien return error_mark_node; 29590075Sobrien 29650397Sobrien if (processing_template_decl) 297169689Skan return build_min (TYPEID_EXPR, const_type_info_type_node, exp); 29850397Sobrien 29950397Sobrien if (TREE_CODE (exp) == INDIRECT_REF 30050397Sobrien && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE 30190075Sobrien && TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) 30250397Sobrien && ! resolves_to_fixed_type_p (exp, &nonnull) 30350397Sobrien && ! nonnull) 30450397Sobrien { 30550397Sobrien exp = stabilize_reference (exp); 30650397Sobrien cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0)); 30750397Sobrien } 30850397Sobrien 30990075Sobrien exp = get_tinfo_decl_dynamic (exp); 31050397Sobrien 31150397Sobrien if (exp == error_mark_node) 31250397Sobrien return error_mark_node; 31350397Sobrien 31450397Sobrien if (cond) 31550397Sobrien { 31650397Sobrien tree bad = throw_bad_typeid (); 31750397Sobrien 318169689Skan exp = build3 (COND_EXPR, TREE_TYPE (exp), cond, exp, bad); 31950397Sobrien } 32050397Sobrien 321132718Skan return exp; 32250397Sobrien} 32350397Sobrien 32490075Sobrien/* Generate the NTBS name of a type. */ 32550397Sobrienstatic tree 326132718Skantinfo_name (tree type) 32750397Sobrien{ 32890075Sobrien const char *name; 32990075Sobrien tree name_string; 33050397Sobrien 33190075Sobrien name = mangle_type_string (type); 332117395Skan name_string = fix_string_type (build_string (strlen (name) + 1, name)); 33390075Sobrien return name_string; 33450397Sobrien} 33550397Sobrien 336102780Skan/* Return a VAR_DECL for the internal ABI defined type_info object for 337102780Skan TYPE. You must arrange that the decl is mark_used, if actually use 338169689Skan it --- decls in vtables are only used if the vtable is output. */ 33960967Sobrien 34050397Sobrientree 341132718Skanget_tinfo_decl (tree type) 34250397Sobrien{ 34350397Sobrien tree name; 34450397Sobrien tree d; 34550397Sobrien 346169689Skan if (variably_modified_type_p (type, /*fn=*/NULL_TREE)) 34790075Sobrien { 348169689Skan error ("cannot create type information for type %qT because " 349169689Skan "it involves types of variable size", 350102780Skan type); 35190075Sobrien return error_mark_node; 35290075Sobrien } 35390075Sobrien 35450397Sobrien if (TREE_CODE (type) == METHOD_TYPE) 35550397Sobrien type = build_function_type (TREE_TYPE (type), 35650397Sobrien TREE_CHAIN (TYPE_ARG_TYPES (type))); 35750397Sobrien 358110611Skan /* For a class type, the variable is cached in the type node 359110611Skan itself. */ 360110611Skan if (CLASS_TYPE_P (type)) 361110611Skan { 362110611Skan d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)); 363110611Skan if (d) 364110611Skan return d; 365110611Skan } 366169689Skan 36790075Sobrien name = mangle_typeinfo_for_type (type); 36850397Sobrien 36990075Sobrien d = IDENTIFIER_GLOBAL_VALUE (name); 370102780Skan if (!d) 37190075Sobrien { 372169689Skan int ix = get_pseudo_ti_index (type); 373169689Skan tinfo_s *ti = VEC_index (tinfo_s, tinfo_descs, ix); 374102780Skan 375169689Skan d = build_lang_decl (VAR_DECL, name, ti->type); 376169689Skan SET_DECL_ASSEMBLER_NAME (d, name); 377169689Skan /* Remember the type it is for. */ 378169689Skan TREE_TYPE (name) = type; 379169689Skan DECL_TINFO_P (d) = 1; 38090075Sobrien DECL_ARTIFICIAL (d) = 1; 381169689Skan DECL_IGNORED_P (d) = 1; 38290075Sobrien TREE_READONLY (d) = 1; 38390075Sobrien TREE_STATIC (d) = 1; 384169689Skan /* Mark the variable as undefined -- but remember that we can 385169689Skan define it later if we need to do so. */ 38690075Sobrien DECL_EXTERNAL (d) = 1; 387169689Skan DECL_NOT_REALLY_EXTERN (d) = 1; 388110611Skan if (CLASS_TYPE_P (type)) 389110611Skan CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d; 390169689Skan set_linkage_according_to_type (type, d); 391169689Skan pushdecl_top_level_and_finish (d, NULL_TREE); 392110611Skan 393132718Skan /* Add decl to the global array of tinfo decls. */ 394169689Skan VEC_safe_push (tree, gc, unemitted_tinfo_decls, d); 39590075Sobrien } 396102780Skan 39750397Sobrien return d; 39850397Sobrien} 39950397Sobrien 400102780Skan/* Return a pointer to a type_info object describing TYPE, suitably 401102780Skan cast to the language defined type. */ 402102780Skan 403102780Skanstatic tree 404132718Skanget_tinfo_ptr (tree type) 405102780Skan{ 406132718Skan tree decl = get_tinfo_decl (type); 407102780Skan 408132718Skan mark_used (decl); 409169689Skan return build_nop (type_info_ptr_type, 410132718Skan build_address (decl)); 411102780Skan} 412102780Skan 41390075Sobrien/* Return the type_info object for TYPE. */ 41460967Sobrien 41552284Sobrientree 416132718Skanget_typeid (tree type) 41750397Sobrien{ 41890075Sobrien if (type == error_mark_node || !typeid_ok_p ()) 41950397Sobrien return error_mark_node; 420169689Skan 42150397Sobrien if (processing_template_decl) 422169689Skan return build_min (TYPEID_EXPR, const_type_info_type_node, type); 42350397Sobrien 42450397Sobrien /* If the type of the type-id is a reference type, the result of the 42550397Sobrien typeid expression refers to a type_info object representing the 42650397Sobrien referenced type. */ 427132718Skan type = non_reference (type); 42850397Sobrien 42950397Sobrien /* The top-level cv-qualifiers of the lvalue expression or the type-id 43050397Sobrien that is the operand of typeid are always ignored. */ 43150397Sobrien type = TYPE_MAIN_VARIANT (type); 43250397Sobrien 433259655Spfg if (CLASS_TYPE_P (type)) 43490075Sobrien type = complete_type_or_else (type, NULL_TREE); 435169689Skan 43690075Sobrien if (!type) 43790075Sobrien return error_mark_node; 43852284Sobrien 439102780Skan return build_indirect_ref (get_tinfo_ptr (type), NULL); 44050397Sobrien} 44150397Sobrien 44250397Sobrien/* Check whether TEST is null before returning RESULT. If TEST is used in 44350397Sobrien RESULT, it must have previously had a save_expr applied to it. */ 44450397Sobrien 44550397Sobrienstatic tree 446132718Skanifnonnull (tree test, tree result) 44750397Sobrien{ 448169689Skan return build3 (COND_EXPR, TREE_TYPE (result), 449169689Skan build2 (EQ_EXPR, boolean_type_node, test, 450169689Skan cp_convert (TREE_TYPE (test), integer_zero_node)), 451169689Skan cp_convert (TREE_TYPE (result), integer_zero_node), 452169689Skan result); 45350397Sobrien} 45450397Sobrien 45550397Sobrien/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working 45650397Sobrien paper. */ 45750397Sobrien 45850397Sobrienstatic tree 459132718Skanbuild_dynamic_cast_1 (tree type, tree expr) 46050397Sobrien{ 46150397Sobrien enum tree_code tc = TREE_CODE (type); 46290075Sobrien tree exprtype = TREE_TYPE (expr); 46350397Sobrien tree dcast_fn; 46452284Sobrien tree old_expr = expr; 46590075Sobrien const char *errstr = NULL; 46650397Sobrien 467169689Skan /* Save casted types in the function's used types hash table. */ 468169689Skan used_types_insert (type); 469169689Skan 47090075Sobrien /* T shall be a pointer or reference to a complete class type, or 47190075Sobrien `pointer to cv void''. */ 47250397Sobrien switch (tc) 47350397Sobrien { 47450397Sobrien case POINTER_TYPE: 47590075Sobrien if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE) 47690075Sobrien break; 477169689Skan /* Fall through. */ 47890075Sobrien case REFERENCE_TYPE: 47990075Sobrien if (! IS_AGGR_TYPE (TREE_TYPE (type))) 48050397Sobrien { 48190075Sobrien errstr = "target is not pointer or reference to class"; 48290075Sobrien goto fail; 48350397Sobrien } 48490075Sobrien if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type)))) 48590075Sobrien { 48690075Sobrien errstr = "target is not pointer or reference to complete type"; 48790075Sobrien goto fail; 48890075Sobrien } 48950397Sobrien break; 49090075Sobrien 49150397Sobrien default: 49290075Sobrien errstr = "target is not pointer or reference"; 49350397Sobrien goto fail; 49450397Sobrien } 49550397Sobrien 49690075Sobrien if (tc == POINTER_TYPE) 49790075Sobrien { 49890075Sobrien /* If T is a pointer type, v shall be an rvalue of a pointer to 49990075Sobrien complete class type, and the result is an rvalue of type T. */ 50090075Sobrien 50190075Sobrien if (TREE_CODE (exprtype) != POINTER_TYPE) 50290075Sobrien { 50390075Sobrien errstr = "source is not a pointer"; 50490075Sobrien goto fail; 50590075Sobrien } 50690075Sobrien if (! IS_AGGR_TYPE (TREE_TYPE (exprtype))) 50790075Sobrien { 50890075Sobrien errstr = "source is not a pointer to class"; 50990075Sobrien goto fail; 51090075Sobrien } 51190075Sobrien if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype)))) 51290075Sobrien { 51390075Sobrien errstr = "source is a pointer to incomplete type"; 51490075Sobrien goto fail; 51590075Sobrien } 51650397Sobrien } 51790075Sobrien else 51890075Sobrien { 519169689Skan exprtype = build_reference_type (exprtype); 520169689Skan 52190075Sobrien /* T is a reference type, v shall be an lvalue of a complete class 52290075Sobrien type, and the result is an lvalue of the type referred to by T. */ 52350397Sobrien 52490075Sobrien if (! IS_AGGR_TYPE (TREE_TYPE (exprtype))) 52590075Sobrien { 52690075Sobrien errstr = "source is not of class type"; 52790075Sobrien goto fail; 52890075Sobrien } 52990075Sobrien if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype)))) 53090075Sobrien { 53190075Sobrien errstr = "source is of incomplete class type"; 53290075Sobrien goto fail; 53390075Sobrien } 534169689Skan 535169689Skan /* Apply trivial conversion T -> T& for dereferenced ptrs. */ 536169689Skan expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, 537169689Skan LOOKUP_NORMAL, NULL_TREE); 53890075Sobrien } 53990075Sobrien 54090075Sobrien /* The dynamic_cast operator shall not cast away constness. */ 54190075Sobrien if (!at_least_as_qualified_p (TREE_TYPE (type), 54290075Sobrien TREE_TYPE (exprtype))) 54390075Sobrien { 54490075Sobrien errstr = "conversion casts away constness"; 54590075Sobrien goto fail; 54690075Sobrien } 54790075Sobrien 54850397Sobrien /* If *type is an unambiguous accessible base class of *exprtype, 54950397Sobrien convert statically. */ 55050397Sobrien { 55190075Sobrien tree binfo; 55250397Sobrien 55390075Sobrien binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type), 554169689Skan ba_check, NULL); 55552284Sobrien 55690075Sobrien if (binfo) 55752284Sobrien { 55890075Sobrien expr = build_base_path (PLUS_EXPR, convert_from_reference (expr), 55990075Sobrien binfo, 0); 56090075Sobrien if (TREE_CODE (exprtype) == POINTER_TYPE) 561169689Skan expr = rvalue (expr); 56290075Sobrien return expr; 56352284Sobrien } 56450397Sobrien } 56550397Sobrien 56650397Sobrien /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */ 56790075Sobrien if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype))) 56850397Sobrien { 56950397Sobrien tree expr1; 57050397Sobrien /* if TYPE is `void *', return pointer to complete object. */ 57190075Sobrien if (tc == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (type))) 57250397Sobrien { 57350397Sobrien /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */ 57450397Sobrien if (TREE_CODE (expr) == ADDR_EXPR 57550397Sobrien && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL 57650397Sobrien && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE) 57750397Sobrien return build1 (NOP_EXPR, type, expr); 57850397Sobrien 57950397Sobrien /* Since expr is used twice below, save it. */ 58050397Sobrien expr = save_expr (expr); 58150397Sobrien 58250397Sobrien expr1 = build_headof (expr); 58350397Sobrien if (TREE_TYPE (expr1) != type) 58450397Sobrien expr1 = build1 (NOP_EXPR, type, expr1); 58550397Sobrien return ifnonnull (expr, expr1); 58650397Sobrien } 58750397Sobrien else 58850397Sobrien { 58950397Sobrien tree retval; 590169689Skan tree result, td2, td3, elems; 591169689Skan tree static_type, target_type, boff; 59250397Sobrien 593169689Skan /* If we got here, we can't convert statically. Therefore, 59450397Sobrien dynamic_cast<D&>(b) (b an object) cannot succeed. */ 59590075Sobrien if (tc == REFERENCE_TYPE) 59650397Sobrien { 59752284Sobrien if (TREE_CODE (old_expr) == VAR_DECL 59852284Sobrien && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE) 59950397Sobrien { 600169689Skan tree expr = throw_bad_cast (); 601169689Skan warning (0, "dynamic_cast of %q#D to %q#T can never succeed", 602169689Skan old_expr, type); 603169689Skan /* Bash it to the expected type. */ 604169689Skan TREE_TYPE (expr) = type; 60590075Sobrien return expr; 60650397Sobrien } 60750397Sobrien } 60850397Sobrien /* Ditto for dynamic_cast<D*>(&b). */ 60950397Sobrien else if (TREE_CODE (expr) == ADDR_EXPR) 61050397Sobrien { 61150397Sobrien tree op = TREE_OPERAND (expr, 0); 61250397Sobrien if (TREE_CODE (op) == VAR_DECL 61350397Sobrien && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE) 61450397Sobrien { 615169689Skan warning (0, "dynamic_cast of %q#D to %q#T can never succeed", 616169689Skan op, type); 617169689Skan retval = build_int_cst (type, 0); 61850397Sobrien return retval; 61950397Sobrien } 62050397Sobrien } 62150397Sobrien 622169689Skan /* Use of dynamic_cast when -fno-rtti is prohibited. */ 623169689Skan if (!flag_rtti) 624169689Skan { 625169689Skan error ("%<dynamic_cast%> not permitted with -fno-rtti"); 626169689Skan return error_mark_node; 627169689Skan } 628169689Skan 62990075Sobrien target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); 63090075Sobrien static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype)); 631132718Skan td2 = get_tinfo_decl (target_type); 632132718Skan mark_used (td2); 633132718Skan td2 = build_unary_op (ADDR_EXPR, td2, 0); 634132718Skan td3 = get_tinfo_decl (static_type); 635132718Skan mark_used (td3); 636132718Skan td3 = build_unary_op (ADDR_EXPR, td3, 0); 63790075Sobrien 638169689Skan /* Determine how T and V are related. */ 639169689Skan boff = dcast_base_hint (static_type, target_type); 640169689Skan 64150397Sobrien /* Since expr is used twice below, save it. */ 64250397Sobrien expr = save_expr (expr); 64350397Sobrien 64450397Sobrien expr1 = expr; 64550397Sobrien if (tc == REFERENCE_TYPE) 64650397Sobrien expr1 = build_unary_op (ADDR_EXPR, expr1, 0); 64750397Sobrien 64890075Sobrien elems = tree_cons 64990075Sobrien (NULL_TREE, expr1, tree_cons 65090075Sobrien (NULL_TREE, td3, tree_cons 65190075Sobrien (NULL_TREE, td2, tree_cons 65290075Sobrien (NULL_TREE, boff, NULL_TREE)))); 65350397Sobrien 65490075Sobrien dcast_fn = dynamic_cast_node; 65590075Sobrien if (!dcast_fn) 65650397Sobrien { 65750397Sobrien tree tmp; 65890075Sobrien tree tinfo_ptr; 65990075Sobrien tree ns = abi_node; 66090075Sobrien const char *name; 661169689Skan 66290075Sobrien push_nested_namespace (ns); 663117395Skan tinfo_ptr = xref_tag (class_type, 66490075Sobrien get_identifier ("__class_type_info"), 665169689Skan /*tag_scope=*/ts_current, false); 666169689Skan 66790075Sobrien tinfo_ptr = build_pointer_type 66890075Sobrien (build_qualified_type 66990075Sobrien (tinfo_ptr, TYPE_QUAL_CONST)); 67090075Sobrien name = "__dynamic_cast"; 67150397Sobrien tmp = tree_cons 67290075Sobrien (NULL_TREE, const_ptr_type_node, tree_cons 67390075Sobrien (NULL_TREE, tinfo_ptr, tree_cons 67490075Sobrien (NULL_TREE, tinfo_ptr, tree_cons 67590075Sobrien (NULL_TREE, ptrdiff_type_node, void_list_node)))); 67650397Sobrien tmp = build_function_type (ptr_type_node, tmp); 67790075Sobrien dcast_fn = build_library_fn_ptr (name, tmp); 678132718Skan DECL_IS_PURE (dcast_fn) = 1; 679169689Skan pop_nested_namespace (ns); 680169689Skan dynamic_cast_node = dcast_fn; 68150397Sobrien } 682169689Skan result = build_cxx_call (dcast_fn, elems); 68350397Sobrien 68450397Sobrien if (tc == REFERENCE_TYPE) 68550397Sobrien { 68690075Sobrien tree bad = throw_bad_cast (); 687169689Skan tree neq; 688169689Skan 68950397Sobrien result = save_expr (result); 690169689Skan neq = c_common_truthvalue_conversion (result); 691169689Skan return build3 (COND_EXPR, type, neq, result, bad); 69250397Sobrien } 69350397Sobrien 69450397Sobrien /* Now back to the type we want from a void*. */ 69550397Sobrien result = cp_convert (type, result); 696169689Skan return ifnonnull (expr, result); 69750397Sobrien } 69850397Sobrien } 69990075Sobrien else 70090075Sobrien errstr = "source type is not polymorphic"; 70150397Sobrien 70250397Sobrien fail: 703169689Skan error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)", 704169689Skan expr, exprtype, type, errstr); 70550397Sobrien return error_mark_node; 70650397Sobrien} 70750397Sobrien 70850397Sobrientree 709132718Skanbuild_dynamic_cast (tree type, tree expr) 71050397Sobrien{ 71150397Sobrien if (type == error_mark_node || expr == error_mark_node) 71250397Sobrien return error_mark_node; 713169689Skan 71450397Sobrien if (processing_template_decl) 715132718Skan { 716132718Skan expr = build_min (DYNAMIC_CAST_EXPR, type, expr); 717132718Skan TREE_SIDE_EFFECTS (expr) = 1; 718169689Skan 719132718Skan return expr; 720132718Skan } 72150397Sobrien 72250397Sobrien return convert_from_reference (build_dynamic_cast_1 (type, expr)); 72350397Sobrien} 72450397Sobrien 72590075Sobrien/* Return the runtime bit mask encoding the qualifiers of TYPE. */ 72650397Sobrien 72790075Sobrienstatic int 728132718Skanqualifier_flags (tree type) 72990075Sobrien{ 73090075Sobrien int flags = 0; 731117395Skan int quals = cp_type_quals (type); 732169689Skan 73390075Sobrien if (quals & TYPE_QUAL_CONST) 73490075Sobrien flags |= 1; 73590075Sobrien if (quals & TYPE_QUAL_VOLATILE) 73690075Sobrien flags |= 2; 73790075Sobrien if (quals & TYPE_QUAL_RESTRICT) 73890075Sobrien flags |= 4; 73990075Sobrien return flags; 74090075Sobrien} 74150397Sobrien 742132718Skan/* Return true, if the pointer chain TYPE ends at an incomplete type, or 74390075Sobrien contains a pointer to member of an incomplete class. */ 74450397Sobrien 745132718Skanstatic bool 746132718Skantarget_incomplete_p (tree type) 74790075Sobrien{ 748132718Skan while (true) 74990075Sobrien if (TYPE_PTRMEM_P (type)) 75090075Sobrien { 751132718Skan if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type))) 752132718Skan return true; 753132718Skan type = TYPE_PTRMEM_POINTED_TO_TYPE (type); 75490075Sobrien } 755132718Skan else if (TREE_CODE (type) == POINTER_TYPE) 756132718Skan type = TREE_TYPE (type); 75790075Sobrien else 758132718Skan return !COMPLETE_OR_VOID_TYPE_P (type); 75990075Sobrien} 76050397Sobrien 761169689Skan/* Returns true if TYPE involves an incomplete class type; in that 762169689Skan case, typeinfo variables for TYPE should be emitted with internal 763169689Skan linkage. */ 764169689Skan 765169689Skanstatic bool 766169689Skaninvolves_incomplete_p (tree type) 767169689Skan{ 768169689Skan switch (TREE_CODE (type)) 769169689Skan { 770169689Skan case POINTER_TYPE: 771169689Skan return target_incomplete_p (TREE_TYPE (type)); 772169689Skan 773169689Skan case OFFSET_TYPE: 774169689Skan ptrmem: 775169689Skan return 776169689Skan (target_incomplete_p (TYPE_PTRMEM_POINTED_TO_TYPE (type)) 777169689Skan || !COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type))); 778169689Skan 779169689Skan case RECORD_TYPE: 780169689Skan if (TYPE_PTRMEMFUNC_P (type)) 781169689Skan goto ptrmem; 782169689Skan /* Fall through. */ 783169689Skan case UNION_TYPE: 784169689Skan if (!COMPLETE_TYPE_P (type)) 785169689Skan return true; 786169689Skan 787169689Skan default: 788169689Skan /* All other types do not involve incomplete class types. */ 789169689Skan return false; 790169689Skan } 791169689Skan} 792169689Skan 79390075Sobrien/* Return a CONSTRUCTOR for the common part of the type_info objects. This 79490075Sobrien is the vtable pointer and NTBS name. The NTBS name is emitted as a 79590075Sobrien comdat const char array, so it becomes a unique key for the type. Generate 79690075Sobrien and emit that VAR_DECL here. (We can't always emit the type_info itself 79790075Sobrien as comdat, because of pointers to incomplete.) */ 79850397Sobrien 79990075Sobrienstatic tree 800169689Skantinfo_base_init (tinfo_s *ti, tree target) 80150397Sobrien{ 80290075Sobrien tree init = NULL_TREE; 80390075Sobrien tree name_decl; 804102780Skan tree vtable_ptr; 805169689Skan 80690075Sobrien { 80790075Sobrien tree name_name; 808169689Skan 80990075Sobrien /* Generate the NTBS array variable. */ 81090075Sobrien tree name_type = build_cplus_array_type 811169689Skan (build_qualified_type (char_type_node, TYPE_QUAL_CONST), 812169689Skan NULL_TREE); 81390075Sobrien tree name_string = tinfo_name (target); 81450397Sobrien 815169689Skan /* Determine the name of the variable -- and remember with which 816169689Skan type it is associated. */ 81790075Sobrien name_name = mangle_typeinfo_string_for_type (target); 818169689Skan TREE_TYPE (name_name) = target; 819169689Skan 82090075Sobrien name_decl = build_lang_decl (VAR_DECL, name_name, name_type); 821169689Skan SET_DECL_ASSEMBLER_NAME (name_decl, name_name); 82290075Sobrien DECL_ARTIFICIAL (name_decl) = 1; 823169689Skan DECL_IGNORED_P (name_decl) = 1; 82490075Sobrien TREE_READONLY (name_decl) = 1; 82590075Sobrien TREE_STATIC (name_decl) = 1; 82690075Sobrien DECL_EXTERNAL (name_decl) = 0; 827169689Skan DECL_TINFO_P (name_decl) = 1; 828169689Skan set_linkage_according_to_type (target, name_decl); 829169689Skan import_export_decl (name_decl); 83090075Sobrien DECL_INITIAL (name_decl) = name_string; 831132718Skan mark_used (name_decl); 832117395Skan pushdecl_top_level_and_finish (name_decl, name_string); 83390075Sobrien } 834102780Skan 835169689Skan vtable_ptr = ti->vtable; 836102780Skan if (!vtable_ptr) 837102780Skan { 838102780Skan tree real_type; 839102780Skan push_nested_namespace (abi_node); 840169689Skan real_type = xref_tag (class_type, ti->name, 841169689Skan /*tag_scope=*/ts_current, false); 842102780Skan pop_nested_namespace (abi_node); 843169689Skan 844102780Skan if (!COMPLETE_TYPE_P (real_type)) 845102780Skan { 846169689Skan /* We never saw a definition of this type, so we need to 847102780Skan tell the compiler that this is an exported class, as 848102780Skan indeed all of the __*_type_info classes are. */ 849102780Skan SET_CLASSTYPE_INTERFACE_KNOWN (real_type); 850102780Skan CLASSTYPE_INTERFACE_ONLY (real_type) = 1; 851102780Skan } 852102780Skan 853102780Skan vtable_ptr = get_vtable_decl (real_type, /*complete=*/1); 854102780Skan vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0); 855102780Skan 856102780Skan /* We need to point into the middle of the vtable. */ 857169689Skan vtable_ptr = build2 858102780Skan (PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr, 859102780Skan size_binop (MULT_EXPR, 860117395Skan size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE), 861102780Skan TYPE_SIZE_UNIT (vtable_entry_type))); 862102780Skan 863169689Skan ti->vtable = vtable_ptr; 86490075Sobrien } 865102780Skan 866102780Skan init = tree_cons (NULL_TREE, vtable_ptr, init); 867169689Skan 86890075Sobrien init = tree_cons (NULL_TREE, decay_conversion (name_decl), init); 869169689Skan 870169689Skan init = build_constructor_from_list (NULL_TREE, nreverse (init)); 871169689Skan TREE_CONSTANT (init) = 1; 872169689Skan TREE_INVARIANT (init) = 1; 873169689Skan TREE_STATIC (init) = 1; 87490075Sobrien init = tree_cons (NULL_TREE, init, NULL_TREE); 875169689Skan 87690075Sobrien return init; 87790075Sobrien} 87850397Sobrien 879169689Skan/* Return the CONSTRUCTOR expr for a type_info of TYPE. TI provides the 88090075Sobrien information about the particular type_info derivation, which adds no 88190075Sobrien additional fields to the type_info base. */ 88290075Sobrien 88390075Sobrienstatic tree 884169689Skangeneric_initializer (tinfo_s *ti, tree target) 88590075Sobrien{ 886169689Skan tree init = tinfo_base_init (ti, target); 887169689Skan 888169689Skan init = build_constructor_from_list (NULL_TREE, init); 889169689Skan TREE_CONSTANT (init) = 1; 890169689Skan TREE_INVARIANT (init) = 1; 891169689Skan TREE_STATIC (init) = 1; 89290075Sobrien return init; 89350397Sobrien} 89450397Sobrien 89590075Sobrien/* Return the CONSTRUCTOR expr for a type_info of pointer TYPE. 896169689Skan TI provides information about the particular type_info derivation, 89790075Sobrien which adds target type and qualifier flags members to the type_info base. */ 89850397Sobrien 89990075Sobrienstatic tree 900169689Skanptr_initializer (tinfo_s *ti, tree target) 90150397Sobrien{ 902169689Skan tree init = tinfo_base_init (ti, target); 90390075Sobrien tree to = TREE_TYPE (target); 90490075Sobrien int flags = qualifier_flags (to); 905132718Skan bool incomplete = target_incomplete_p (to); 906169689Skan 90790075Sobrien if (incomplete) 908169689Skan flags |= 8; 909169689Skan init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init); 91090075Sobrien init = tree_cons (NULL_TREE, 911169689Skan get_tinfo_ptr (TYPE_MAIN_VARIANT (to)), 912169689Skan init); 913169689Skan 914169689Skan init = build_constructor_from_list (NULL_TREE, nreverse (init)); 915169689Skan TREE_CONSTANT (init) = 1; 916169689Skan TREE_INVARIANT (init) = 1; 917169689Skan TREE_STATIC (init) = 1; 91890075Sobrien return init; 91990075Sobrien} 92050397Sobrien 92190075Sobrien/* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE. 922169689Skan TI provides information about the particular type_info derivation, 92390075Sobrien which adds class, target type and qualifier flags members to the type_info 92490075Sobrien base. */ 92550397Sobrien 92690075Sobrienstatic tree 927169689Skanptm_initializer (tinfo_s *ti, tree target) 92890075Sobrien{ 929169689Skan tree init = tinfo_base_init (ti, target); 93090075Sobrien tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target); 93190075Sobrien tree klass = TYPE_PTRMEM_CLASS_TYPE (target); 93290075Sobrien int flags = qualifier_flags (to); 933132718Skan bool incomplete = target_incomplete_p (to); 934169689Skan 93590075Sobrien if (incomplete) 936169689Skan flags |= 0x8; 93790075Sobrien if (!COMPLETE_TYPE_P (klass)) 938169689Skan flags |= 0x10; 939169689Skan init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init); 94090075Sobrien init = tree_cons (NULL_TREE, 941102780Skan get_tinfo_ptr (TYPE_MAIN_VARIANT (to)), 942169689Skan init); 94390075Sobrien init = tree_cons (NULL_TREE, 944102780Skan get_tinfo_ptr (klass), 945169689Skan init); 94650397Sobrien 947169689Skan init = build_constructor_from_list (NULL_TREE, nreverse (init)); 948169689Skan TREE_CONSTANT (init) = 1; 949169689Skan TREE_INVARIANT (init) = 1; 950169689Skan TREE_STATIC (init) = 1; 951169689Skan return init; 952132718Skan} 95350397Sobrien 95490075Sobrien/* Return the CONSTRUCTOR expr for a type_info of class TYPE. 955169689Skan TI provides information about the particular __class_type_info derivation, 95690075Sobrien which adds hint flags and TRAIL initializers to the type_info base. */ 95750397Sobrien 95890075Sobrienstatic tree 959169689Skanclass_initializer (tinfo_s *ti, tree target, tree trail) 96090075Sobrien{ 961169689Skan tree init = tinfo_base_init (ti, target); 962169689Skan 96390075Sobrien TREE_CHAIN (init) = trail; 964169689Skan init = build_constructor_from_list (NULL_TREE, init); 965169689Skan TREE_CONSTANT (init) = 1; 966169689Skan TREE_INVARIANT (init) = 1; 967169689Skan TREE_STATIC (init) = 1; 968169689Skan return init; 96990075Sobrien} 97050397Sobrien 971132718Skan/* Returns true if the typeinfo for type should be placed in 97290075Sobrien the runtime library. */ 97350397Sobrien 974132718Skanstatic bool 975132718Skantypeinfo_in_lib_p (tree type) 97690075Sobrien{ 97790075Sobrien /* The typeinfo objects for `T*' and `const T*' are in the runtime 97890075Sobrien library for simple types T. */ 97990075Sobrien if (TREE_CODE (type) == POINTER_TYPE 98090075Sobrien && (cp_type_quals (TREE_TYPE (type)) == TYPE_QUAL_CONST 98190075Sobrien || cp_type_quals (TREE_TYPE (type)) == TYPE_UNQUALIFIED)) 98290075Sobrien type = TREE_TYPE (type); 98350397Sobrien 98490075Sobrien switch (TREE_CODE (type)) 98590075Sobrien { 98690075Sobrien case INTEGER_TYPE: 98790075Sobrien case BOOLEAN_TYPE: 98890075Sobrien case REAL_TYPE: 98990075Sobrien case VOID_TYPE: 990132718Skan return true; 991169689Skan 99290075Sobrien default: 993132718Skan return false; 99490075Sobrien } 99590075Sobrien} 99650397Sobrien 997169689Skan/* Generate the initializer for the type info describing TYPE. TK_INDEX is 998169689Skan the index of the descriptor in the tinfo_desc vector. */ 99990075Sobrien 100090075Sobrienstatic tree 1001169689Skanget_pseudo_ti_init (tree type, unsigned tk_index) 100290075Sobrien{ 1003169689Skan tinfo_s *ti = VEC_index (tinfo_s, tinfo_descs, tk_index); 1004169689Skan 1005169689Skan gcc_assert (at_eof); 1006169689Skan switch (tk_index) 100790075Sobrien { 1008169689Skan case TK_POINTER_MEMBER_TYPE: 1009169689Skan return ptm_initializer (ti, type); 1010102780Skan 1011169689Skan case TK_POINTER_TYPE: 1012169689Skan return ptr_initializer (ti, type); 101350397Sobrien 1014169689Skan case TK_BUILTIN_TYPE: 1015169689Skan case TK_ENUMERAL_TYPE: 1016169689Skan case TK_FUNCTION_TYPE: 1017169689Skan case TK_ARRAY_TYPE: 1018169689Skan return generic_initializer (ti, type); 1019169689Skan 1020169689Skan case TK_CLASS_TYPE: 1021169689Skan return class_initializer (ti, type, NULL_TREE); 1022169689Skan 1023169689Skan case TK_SI_CLASS_TYPE: 1024169689Skan { 1025169689Skan tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0); 1026169689Skan tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); 1027169689Skan tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE); 1028169689Skan 1029169689Skan /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */ 1030169689Skan ti = VEC_index (tinfo_s, tinfo_descs, tk_index); 1031169689Skan return class_initializer (ti, type, base_inits); 1032169689Skan } 1033169689Skan 103490075Sobrien default: 1035169689Skan { 1036169689Skan int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0) 1037169689Skan | (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1)); 1038169689Skan tree binfo = TYPE_BINFO (type); 1039169689Skan int nbases = BINFO_N_BASE_BINFOS (binfo); 1040169689Skan VEC(tree,gc) *base_accesses = BINFO_BASE_ACCESSES (binfo); 1041169689Skan tree base_inits = NULL_TREE; 1042169689Skan int ix; 1043169689Skan 1044169689Skan gcc_assert (tk_index >= TK_FIXED); 1045169689Skan 1046169689Skan /* Generate the base information initializer. */ 1047169689Skan for (ix = nbases; ix--;) 1048169689Skan { 1049169689Skan tree base_binfo = BINFO_BASE_BINFO (binfo, ix); 1050169689Skan tree base_init = NULL_TREE; 1051169689Skan int flags = 0; 1052169689Skan tree tinfo; 1053169689Skan tree offset; 1054169689Skan 1055169689Skan if (VEC_index (tree, base_accesses, ix) == access_public_node) 1056169689Skan flags |= 2; 1057169689Skan tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); 1058169689Skan if (BINFO_VIRTUAL_P (base_binfo)) 1059169689Skan { 1060169689Skan /* We store the vtable offset at which the virtual 1061169689Skan base offset can be found. */ 1062169689Skan offset = BINFO_VPTR_FIELD (base_binfo); 1063169689Skan offset = convert (sizetype, offset); 1064169689Skan flags |= 1; 1065169689Skan } 1066169689Skan else 1067169689Skan offset = BINFO_OFFSET (base_binfo); 1068169689Skan 1069169689Skan /* Combine offset and flags into one field. */ 1070169689Skan offset = cp_build_binary_op (LSHIFT_EXPR, offset, 1071169689Skan build_int_cst (NULL_TREE, 8)); 1072169689Skan offset = cp_build_binary_op (BIT_IOR_EXPR, offset, 1073169689Skan build_int_cst (NULL_TREE, flags)); 1074169689Skan base_init = tree_cons (NULL_TREE, offset, base_init); 1075169689Skan base_init = tree_cons (NULL_TREE, tinfo, base_init); 1076169689Skan base_init = build_constructor_from_list (NULL_TREE, base_init); 1077169689Skan base_inits = tree_cons (NULL_TREE, base_init, base_inits); 1078169689Skan } 1079169689Skan base_inits = build_constructor_from_list (NULL_TREE, base_inits); 1080169689Skan base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE); 1081169689Skan /* Prepend the number of bases. */ 1082169689Skan base_inits = tree_cons (NULL_TREE, 1083169689Skan build_int_cst (NULL_TREE, nbases), 1084169689Skan base_inits); 1085169689Skan /* Prepend the hint flags. */ 1086169689Skan base_inits = tree_cons (NULL_TREE, 1087169689Skan build_int_cst (NULL_TREE, hint), 1088169689Skan base_inits); 1089169689Skan 1090169689Skan /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */ 1091169689Skan ti = VEC_index (tinfo_s, tinfo_descs, tk_index); 1092169689Skan return class_initializer (ti, type, base_inits); 1093169689Skan } 109450397Sobrien } 109590075Sobrien} 109650397Sobrien 109790075Sobrien/* Generate the RECORD_TYPE containing the data layout of a type_info 109890075Sobrien derivative as used by the runtime. This layout must be consistent with 109990075Sobrien that defined in the runtime support. Also generate the VAR_DECL for the 110090075Sobrien type's vtable. We explicitly manage the vtable member, and name it for 110190075Sobrien real type as used in the runtime. The RECORD type has a different name, 110290075Sobrien to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE 1103102780Skan is the generated type and TINFO_VTABLE_NAME is the name of the 1104102780Skan vtable. We have to delay generating the VAR_DECL of the vtable 1105102780Skan until the end of the translation, when we'll have seen the library 1106102780Skan definition, if there was one. 1107169689Skan 110890075Sobrien REAL_NAME is the runtime's name of the type. Trailing arguments are 110990075Sobrien additional FIELD_DECL's for the structure. The final argument must be 111090075Sobrien NULL. */ 111150397Sobrien 1112169689Skanstatic void 1113169689Skancreate_pseudo_type_info (int tk, const char *real_name, ...) 111450397Sobrien{ 1115169689Skan tinfo_s *ti; 1116102780Skan tree pseudo_type; 111790075Sobrien char *pseudo_name; 1118132718Skan tree fields; 111990075Sobrien tree field_decl; 1120132718Skan va_list ap; 112150397Sobrien 1122169689Skan va_start (ap, real_name); 112350397Sobrien 1124117395Skan /* Generate the pseudo type name. */ 1125169689Skan pseudo_name = (char *) alloca (strlen (real_name) + 30); 112690075Sobrien strcpy (pseudo_name, real_name); 112790075Sobrien strcat (pseudo_name, "_pseudo"); 1128169689Skan if (tk >= TK_FIXED) 1129169689Skan sprintf (pseudo_name + strlen (pseudo_name), "%d", tk - TK_FIXED); 1130169689Skan 1131117395Skan /* First field is the pseudo type_info base class. */ 1132169689Skan fields = build_decl (FIELD_DECL, NULL_TREE, 1133169689Skan VEC_index (tinfo_s, tinfo_descs, 1134169689Skan TK_TYPE_INFO_TYPE)->type); 1135169689Skan 113690075Sobrien /* Now add the derived fields. */ 1137132718Skan while ((field_decl = va_arg (ap, tree))) 1138132718Skan { 1139132718Skan TREE_CHAIN (field_decl) = fields; 1140132718Skan fields = field_decl; 1141132718Skan } 1142169689Skan 1143117395Skan /* Create the pseudo type. */ 114490075Sobrien pseudo_type = make_aggr_type (RECORD_TYPE); 1145132718Skan finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE); 1146117395Skan CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type; 114790075Sobrien 1148169689Skan ti = VEC_index (tinfo_s, tinfo_descs, tk); 1149169689Skan ti->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST); 1150169689Skan ti->name = get_identifier (real_name); 1151169689Skan ti->vtable = NULL_TREE; 1152169689Skan 1153169689Skan /* Pretend this is public so determine_visibility doesn't give vtables 1154169689Skan internal linkage. */ 1155169689Skan TREE_PUBLIC (TYPE_MAIN_DECL (ti->type)) = 1; 1156169689Skan 1157132718Skan va_end (ap); 115850397Sobrien} 115950397Sobrien 1160169689Skan/* Return the index of a pseudo type info type node used to describe 1161169689Skan TYPE. TYPE must be a complete type (or cv void), except at the end 1162169689Skan of the translation unit. */ 116350397Sobrien 1164169689Skanstatic unsigned 1165169689Skanget_pseudo_ti_index (tree type) 116650397Sobrien{ 1167169689Skan unsigned ix; 1168169689Skan 1169102780Skan switch (TREE_CODE (type)) 117050397Sobrien { 1171132718Skan case OFFSET_TYPE: 1172169689Skan ix = TK_POINTER_MEMBER_TYPE; 1173169689Skan break; 1174169689Skan 1175102780Skan case POINTER_TYPE: 1176169689Skan ix = TK_POINTER_TYPE; 1177169689Skan break; 1178169689Skan 1179102780Skan case ENUMERAL_TYPE: 1180169689Skan ix = TK_ENUMERAL_TYPE; 1181169689Skan break; 1182169689Skan 1183102780Skan case FUNCTION_TYPE: 1184169689Skan ix = TK_FUNCTION_TYPE; 1185169689Skan break; 1186169689Skan 1187102780Skan case ARRAY_TYPE: 1188169689Skan ix = TK_ARRAY_TYPE; 1189169689Skan break; 1190169689Skan 1191102780Skan case UNION_TYPE: 1192102780Skan case RECORD_TYPE: 1193102780Skan if (TYPE_PTRMEMFUNC_P (type)) 1194169689Skan { 1195169689Skan ix = TK_POINTER_MEMBER_TYPE; 1196169689Skan break; 1197169689Skan } 1198102780Skan else if (!COMPLETE_TYPE_P (type)) 1199102780Skan { 1200117395Skan if (!at_eof) 1201117395Skan cxx_incomplete_type_error (NULL_TREE, type); 1202169689Skan ix = TK_CLASS_TYPE; 1203169689Skan break; 1204102780Skan } 1205169689Skan else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type))) 1206169689Skan { 1207169689Skan ix = TK_CLASS_TYPE; 1208169689Skan break; 1209169689Skan } 1210102780Skan else 1211102780Skan { 1212132718Skan tree binfo = TYPE_BINFO (type); 1213169689Skan VEC(tree,gc) *base_accesses = BINFO_BASE_ACCESSES (binfo); 1214169689Skan tree base_binfo = BINFO_BASE_BINFO (binfo, 0); 1215169689Skan int num_bases = BINFO_N_BASE_BINFOS (binfo); 1216169689Skan 1217102780Skan if (num_bases == 1 1218169689Skan && VEC_index (tree, base_accesses, 0) == access_public_node 1219169689Skan && !BINFO_VIRTUAL_P (base_binfo) 1220102780Skan && integer_zerop (BINFO_OFFSET (base_binfo))) 1221169689Skan { 1222169689Skan /* single non-virtual public. */ 1223169689Skan ix = TK_SI_CLASS_TYPE; 1224169689Skan break; 1225169689Skan } 1226102780Skan else 1227102780Skan { 1228169689Skan tinfo_s *ti; 1229102780Skan tree array_domain, base_array; 1230169689Skan 1231169689Skan ix = TK_FIXED + num_bases; 1232169689Skan if (VEC_length (tinfo_s, tinfo_descs) <= ix) 1233102780Skan { 1234169689Skan /* too short, extend. */ 1235169689Skan unsigned len = VEC_length (tinfo_s, tinfo_descs); 1236169689Skan 1237169689Skan VEC_safe_grow (tinfo_s, gc, tinfo_descs, ix + 1); 1238169689Skan while (VEC_iterate (tinfo_s, tinfo_descs, len++, ti)) 1239169689Skan ti->type = ti->vtable = ti->name = NULL_TREE; 1240102780Skan } 1241169689Skan else if (VEC_index (tinfo_s, tinfo_descs, ix)->type) 1242169689Skan /* already created. */ 1243169689Skan break; 1244169689Skan 1245132718Skan /* Create the array of __base_class_type_info entries. 1246132718Skan G++ 3.2 allocated an array that had one too many 1247132718Skan entries, and then filled that extra entries with 1248132718Skan zeros. */ 1249132718Skan if (abi_version_at_least (2)) 1250132718Skan array_domain = build_index_type (size_int (num_bases - 1)); 1251132718Skan else 1252132718Skan array_domain = build_index_type (size_int (num_bases)); 1253102780Skan base_array = 1254169689Skan build_array_type (VEC_index (tinfo_s, tinfo_descs, 1255169689Skan TK_BASE_TYPE)->type, 1256169689Skan array_domain); 125750397Sobrien 1258102780Skan push_nested_namespace (abi_node); 1259169689Skan create_pseudo_type_info 1260169689Skan (ix, "__vmi_class_type_info", 1261102780Skan build_decl (FIELD_DECL, NULL_TREE, integer_type_node), 1262102780Skan build_decl (FIELD_DECL, NULL_TREE, integer_type_node), 1263102780Skan build_decl (FIELD_DECL, NULL_TREE, base_array), 1264102780Skan NULL); 1265102780Skan pop_nested_namespace (abi_node); 1266169689Skan break; 1267102780Skan } 1268102780Skan } 1269102780Skan default: 1270169689Skan ix = TK_BUILTIN_TYPE; 1271169689Skan break; 1272102780Skan } 1273169689Skan return ix; 127450397Sobrien} 127550397Sobrien 127690075Sobrien/* Make sure the required builtin types exist for generating the type_info 1277169689Skan variable definitions. */ 127850397Sobrien 127950397Sobrienstatic void 1280132718Skancreate_tinfo_types (void) 128150397Sobrien{ 1282169689Skan tinfo_s *ti; 1283102780Skan 1284169689Skan gcc_assert (!tinfo_descs); 1285169689Skan 1286169689Skan VEC_safe_grow (tinfo_s, gc, tinfo_descs, TK_FIXED); 1287169689Skan 128890075Sobrien push_nested_namespace (abi_node); 1289169689Skan 129090075Sobrien /* Create the internal type_info structure. This is used as a base for 129190075Sobrien the other structures. */ 129290075Sobrien { 1293132718Skan tree field, fields; 129450397Sobrien 1295132718Skan field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node); 1296132718Skan fields = field; 1297169689Skan 1298132718Skan field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node); 1299132718Skan TREE_CHAIN (field) = fields; 1300132718Skan fields = field; 1301169689Skan 1302169689Skan ti = VEC_index (tinfo_s, tinfo_descs, TK_TYPE_INFO_TYPE); 1303169689Skan ti->type = make_aggr_type (RECORD_TYPE); 1304169689Skan ti->vtable = NULL_TREE; 1305169689Skan ti->name = NULL_TREE; 1306169689Skan finish_builtin_struct (ti->type, "__type_info_pseudo", 1307132718Skan fields, NULL_TREE); 1308169689Skan TYPE_HAS_CONSTRUCTOR (ti->type) = 1; 130990075Sobrien } 1310169689Skan 131190075Sobrien /* Fundamental type_info */ 1312169689Skan create_pseudo_type_info (TK_BUILTIN_TYPE, "__fundamental_type_info", NULL); 131350397Sobrien 1314117395Skan /* Array, function and enum type_info. No additional fields. */ 1315169689Skan create_pseudo_type_info (TK_ARRAY_TYPE, "__array_type_info", NULL); 1316169689Skan create_pseudo_type_info (TK_FUNCTION_TYPE, "__function_type_info", NULL); 1317169689Skan create_pseudo_type_info (TK_ENUMERAL_TYPE, "__enum_type_info", NULL); 1318169689Skan 1319169689Skan /* Class type_info. No additional fields. */ 1320169689Skan create_pseudo_type_info (TK_CLASS_TYPE, "__class_type_info", NULL); 1321169689Skan 1322169689Skan /* Single public non-virtual base class. Add pointer to base class. 132390075Sobrien This is really a descendant of __class_type_info. */ 1324169689Skan create_pseudo_type_info (TK_SI_CLASS_TYPE, "__si_class_type_info", 1325169689Skan build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), 1326169689Skan NULL); 1327169689Skan 132890075Sobrien /* Base class internal helper. Pointer to base type, offset to base, 1329117395Skan flags. */ 133090075Sobrien { 1331132718Skan tree field, fields; 1332169689Skan 1333132718Skan field = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type); 1334132718Skan fields = field; 1335169689Skan 1336132718Skan field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]); 1337132718Skan TREE_CHAIN (field) = fields; 1338132718Skan fields = field; 1339169689Skan 1340169689Skan ti = VEC_index (tinfo_s, tinfo_descs, TK_BASE_TYPE); 1341169689Skan 1342169689Skan ti->type = make_aggr_type (RECORD_TYPE); 1343169689Skan ti->vtable = NULL_TREE; 1344169689Skan ti->name = NULL_TREE; 1345169689Skan finish_builtin_struct (ti->type, "__base_class_type_info_pseudo", 1346132718Skan fields, NULL_TREE); 1347169689Skan TYPE_HAS_CONSTRUCTOR (ti->type) = 1; 134890075Sobrien } 1349169689Skan 135090075Sobrien /* Pointer type_info. Adds two fields, qualification mask 135190075Sobrien and pointer to the pointed to type. This is really a descendant of 1352117395Skan __pbase_type_info. */ 1353169689Skan create_pseudo_type_info (TK_POINTER_TYPE, "__pointer_type_info", 135490075Sobrien build_decl (FIELD_DECL, NULL_TREE, integer_type_node), 1355102780Skan build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), 135690075Sobrien NULL); 135750397Sobrien 135890075Sobrien /* Pointer to member data type_info. Add qualifications flags, 135990075Sobrien pointer to the member's type info and pointer to the class. 136090075Sobrien This is really a descendant of __pbase_type_info. */ 1361169689Skan create_pseudo_type_info (TK_POINTER_MEMBER_TYPE, 1362169689Skan "__pointer_to_member_type_info", 1363169689Skan build_decl (FIELD_DECL, NULL_TREE, integer_type_node), 1364169689Skan build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), 1365169689Skan build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type), 1366169689Skan NULL); 136750397Sobrien 136890075Sobrien pop_nested_namespace (abi_node); 136990075Sobrien} 137050397Sobrien 137190075Sobrien/* Emit the type_info descriptors which are guaranteed to be in the runtime 137290075Sobrien support. Generating them here guarantees consistency with the other 137390075Sobrien structures. We use the following heuristic to determine when the runtime 137490075Sobrien is being generated. If std::__fundamental_type_info is defined, and its 137590075Sobrien destructor is defined, then the runtime is being built. */ 137690075Sobrien 137750397Sobrienvoid 1378132718Skanemit_support_tinfos (void) 137950397Sobrien{ 138090075Sobrien static tree *const fundamentals[] = 138190075Sobrien { 138290075Sobrien &void_type_node, 138390075Sobrien &boolean_type_node, 138490075Sobrien &wchar_type_node, 138590075Sobrien &char_type_node, &signed_char_type_node, &unsigned_char_type_node, 138690075Sobrien &short_integer_type_node, &short_unsigned_type_node, 138790075Sobrien &integer_type_node, &unsigned_type_node, 138890075Sobrien &long_integer_type_node, &long_unsigned_type_node, 138990075Sobrien &long_long_integer_type_node, &long_long_unsigned_type_node, 139090075Sobrien &float_type_node, &double_type_node, &long_double_type_node, 139190075Sobrien 0 139290075Sobrien }; 139390075Sobrien int ix; 139490075Sobrien tree bltn_type, dtor; 1395169689Skan 139690075Sobrien push_nested_namespace (abi_node); 1397117395Skan bltn_type = xref_tag (class_type, 1398169689Skan get_identifier ("__fundamental_type_info"), 1399169689Skan /*tag_scope=*/ts_current, false); 140090075Sobrien pop_nested_namespace (abi_node); 140190075Sobrien if (!COMPLETE_TYPE_P (bltn_type)) 140290075Sobrien return; 1403169689Skan dtor = CLASSTYPE_DESTRUCTORS (bltn_type); 1404169689Skan if (!dtor || DECL_EXTERNAL (dtor)) 140590075Sobrien return; 140690075Sobrien doing_runtime = 1; 140790075Sobrien for (ix = 0; fundamentals[ix]; ix++) 140850397Sobrien { 140990075Sobrien tree bltn = *fundamentals[ix]; 1410169689Skan tree types[3]; 1411169689Skan int i; 141250397Sobrien 1413169689Skan types[0] = bltn; 1414169689Skan types[1] = build_pointer_type (bltn); 1415169689Skan types[2] = build_pointer_type (build_qualified_type (bltn, 1416169689Skan TYPE_QUAL_CONST)); 141750397Sobrien 1418169689Skan for (i = 0; i < 3; ++i) 1419169689Skan { 1420169689Skan tree tinfo; 1421169689Skan 1422169689Skan tinfo = get_tinfo_decl (types[i]); 1423169689Skan TREE_USED (tinfo) = 1; 1424169689Skan mark_needed (tinfo); 1425169689Skan /* The C++ ABI requires that these objects be COMDAT. But, 1426169689Skan On systems without weak symbols, initialized COMDAT 1427169689Skan objects are emitted with internal linkage. (See 1428169689Skan comdat_linkage for details.) Since we want these objects 1429169689Skan to have external linkage so that copies do not have to be 1430169689Skan emitted in code outside the runtime library, we make them 1431259649Spfg non-COMDAT here. 1432259649Spfg 1433259649Spfg It might also not be necessary to follow this detail of the 1434259649Spfg ABI. */ 1435259649Spfg if (!flag_weak || ! targetm.cxx.library_rtti_comdat ()) 1436169689Skan { 1437169689Skan gcc_assert (TREE_PUBLIC (tinfo) && !DECL_COMDAT (tinfo)); 1438169689Skan DECL_INTERFACE_KNOWN (tinfo) = 1; 1439169689Skan } 1440169689Skan } 1441169689Skan } 144290075Sobrien} 144350397Sobrien 1444102780Skan/* Finish a type info decl. DECL_PTR is a pointer to an unemitted 1445102780Skan tinfo decl. Determine whether it needs emitting, and if so 1446102780Skan generate the initializer. */ 144750397Sobrien 1448132718Skanbool 1449132718Skanemit_tinfo_decl (tree decl) 145090075Sobrien{ 1451102780Skan tree type = TREE_TYPE (DECL_NAME (decl)); 1452102780Skan int in_library = typeinfo_in_lib_p (type); 1453132718Skan 1454169689Skan gcc_assert (DECL_TINFO_P (decl)); 1455102780Skan 1456169689Skan if (in_library) 1457169689Skan { 1458169689Skan if (doing_runtime) 1459169689Skan DECL_EXTERNAL (decl) = 0; 1460169689Skan else 1461169689Skan { 1462169689Skan /* If we're not in the runtime, then DECL (which is already 1463169689Skan DECL_EXTERNAL) will not be defined here. */ 1464169689Skan DECL_INTERFACE_KNOWN (decl) = 1; 1465169689Skan return false; 1466169689Skan } 1467169689Skan } 1468169689Skan else if (involves_incomplete_p (type)) 1469169689Skan { 1470169689Skan if (!decl_needed_p (decl)) 1471169689Skan return false; 1472169689Skan /* If TYPE involves an incomplete class type, then the typeinfo 1473169689Skan object will be emitted with internal linkage. There is no 1474169689Skan way to know whether or not types are incomplete until the end 1475169689Skan of the compilation, so this determination must be deferred 1476169689Skan until this point. */ 1477169689Skan TREE_PUBLIC (decl) = 0; 1478169689Skan DECL_EXTERNAL (decl) = 0; 1479169689Skan DECL_INTERFACE_KNOWN (decl) = 1; 1480169689Skan } 1481102780Skan 1482169689Skan import_export_decl (decl); 1483169689Skan if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl)) 1484169689Skan { 1485169689Skan tree init; 1486102780Skan 1487169689Skan DECL_EXTERNAL (decl) = 0; 1488169689Skan init = get_pseudo_ti_init (type, get_pseudo_ti_index (type)); 1489169689Skan DECL_INITIAL (decl) = init; 1490169689Skan mark_used (decl); 1491169689Skan finish_decl (decl, init, NULL_TREE); 1492169689Skan return true; 1493169689Skan } 1494169689Skan else 1495169689Skan return false; 1496169689Skan} 1497102780Skan 1498169689Skan#include "gt-cp-rtti.h" 1499