diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog.apple-ppc | 5 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 38 | ||||
-rw-r--r-- | gcc/cp/call.c | 73 | ||||
-rw-r--r-- | gcc/cp/class.c | 205 | ||||
-rw-r--r-- | gcc/cp/cp-dmp-tree.c | 1326 | ||||
-rw-r--r-- | gcc/cp/cp-idebug.c | 463 | ||||
-rw-r--r-- | gcc/cp/cp-lang.c | 63 | ||||
-rw-r--r-- | gcc/cp/cp-root.h | 4 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 55 | ||||
-rw-r--r-- | gcc/cp/decl.c | 234 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 102 | ||||
-rw-r--r-- | gcc/cp/g++spec.c | 11 | ||||
-rw-r--r-- | gcc/cp/init.c | 10 | ||||
-rw-r--r-- | gcc/cp/lang-specs.h | 5 | ||||
-rw-r--r-- | gcc/cp/lex.c | 62 | ||||
-rw-r--r-- | gcc/cp/lex.h | 15 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 29 | ||||
-rw-r--r-- | gcc/cp/method.c | 8 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 194 | ||||
-rw-r--r-- | gcc/cp/pt.c | 6 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 9 | ||||
-rw-r--r-- | gcc/cp/tree.c | 12 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 283 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 10 |
24 files changed, 3174 insertions, 48 deletions
diff --git a/gcc/cp/ChangeLog.apple-ppc b/gcc/cp/ChangeLog.apple-ppc new file mode 100644 index 00000000000..775d813b0ae --- /dev/null +++ b/gcc/cp/ChangeLog.apple-ppc @@ -0,0 +1,5 @@ +2004-04-02 Ziemowit Laski <zlaski@apple.com> + + Remove APPLE LOCAL AltiVec code whenever possible; merge in + AltiVec/VECTOR_TYPE-handling code from mainline. + diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index eb87c256dd5..f67b2500993 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -69,6 +69,15 @@ g++-cross$(exeext): g++$(exeext) -rm -f g++-cross$(exeext) cp g++$(exeext) g++-cross$(exeext) +# APPLE LOCAL begin order files ilr +ifeq ($(ORDER_FILES),yes) +CC1PLUS_ORDER_FLAGS = `if [ -f $(srcdir)/../order-files/cc1plus.order ]; then \ + echo -sectorder __TEXT __text $(srcdir)/../order-files/cc1plus.order -e start ; fi` +else +CC1PLUS_ORDER_FLAGS = +endif +# APPLE LOCAL end order files ilr + # The compiler itself. # Shared with C front end: CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \ @@ -77,20 +86,29 @@ CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \ c-simplify.o tree-inline.o # Language-specific object files. -CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ +# APPLE LOCAL Objective-C++ +CXX_AND_OBJCP_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parser.o cp/ptree.o cp/rtti.o \ cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \ cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \ - cp/mangle.o cp/cp-lang.o cp/name-lookup.o cp/cxx-pretty-print.o \ + cp/mangle.o cp/name-lookup.o cp/cxx-pretty-print.o \ cp/cp-simplify.o tree-mudflap.o cp/cp-mudflap.o +# APPLE LOCAL begin Objective-C++ +# APPLE LOCAL debugging +CXX_OBJS = $(CXX_AND_OBJCP_OBJS) cp/cp-lang.o cp/cp-idebug.o \ + stub-objc.o # cp/cp-dmp-tree.o +# APPLE LOCAL end Objective-C++ + # Use strict warnings for this front end. cp-warn = $(STRICT_WARN) $(WERROR) +# APPLE LOCAL order files ilr cc1plus$(exeext): $(CXX_OBJS) $(CXX_C_OBJS) $(BACKEND) \ libcpp.a $(LIBDEPS) $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \ - $(CXX_OBJS) $(CXX_C_OBJS) $(BACKEND) libcpp.a $(LIBS) + $(CXX_OBJS) $(CXX_C_OBJS) $(BACKEND) libcpp.a $(LIBS) \ + $(CC1PLUS_ORDER_FLAGS) # Special build rules. $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf @@ -260,7 +278,19 @@ cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \ input.h $(PARAMS_H) debug.h tree-inline.h tree-simple.h -cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $(TM_P_H) +cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h \ + $(TARGET_H) $(TM_P_H) + +# APPLE LOCAL debugging +# Suppress all warnings explicitly for the idebug builds since there can be +# many when, and if, -traditional-cpp is used. +cp/cp-idebug.o: cp/cp-idebug.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h idebug.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \ + -w -Wno-traditional $(srcdir)/cp/cp-idebug.c -o cp/cp-idebug.o + +# APPLE LOCAL new tree dump +cp/cp-dmp-tree.o: cp/cp-dmp-tree.c $(CXX_TREE_H) $(SYSTEM_H) $(TM_H) coretypes.h \ + dmp-tree.h c-dmp-tree.c cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h \ output.h diff --git a/gcc/cp/call.c b/gcc/cp/call.c index b8d72f4f348..3020b9c6543 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -660,8 +660,7 @@ standard_conversion (tree to, tree from, tree expr) else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE - && ((*targetm.vector_opaque_p) (TREE_TYPE (to)) - || (*targetm.vector_opaque_p) (TREE_TYPE (from)))) + && vector_types_compatible_p (TREE_TYPE (to), TREE_TYPE (from))) conv = build_conv (ck_std, to, conv); else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE) || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE)) @@ -820,8 +819,7 @@ standard_conversion (tree to, tree from, tree expr) conv->rank = cr_promotion; } else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE - && ((*targetm.vector_opaque_p) (from) - || (*targetm.vector_opaque_p) (to))) + && vector_types_compatible_p (from, to)) return build_conv (ck_std, to, conv); else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) && is_properly_derived_from (from, to)) @@ -3363,7 +3361,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) We need to force the lvalue-to-rvalue conversion here for class types, so we get TARGET_EXPRs; trying to deal with a COND_EXPR of class rvalues that isn't wrapped with a TARGET_EXPR plays havoc with exception - regions. */ + regions. */ arg2 = force_rvalue (arg2); if (!CLASS_TYPE_P (arg2_type)) @@ -4061,6 +4059,36 @@ enforce_access (tree basetype_path, tree decl) return true; } +/* APPLE LOCAL begin direct-binding-refs turly 20020224 */ + +/* Should we *really* call a constructor for the object whose reference type + we want? If we have a user conversion function which returns the ref + type directly, there's no need to call the object's constructor as we + can bind directly (dcl.init.ref.) + + These must be exactly the same types. */ + +static int really_call_constructor_p (tree, tree, tree); +static int +really_call_constructor_p (tree expr, tree convfn, tree totype) +{ + /* TEMPORARILY DISABLING THIS "FIX" NOW WE HAVE A SOURCE WORKAROUND. */ + /* However, we'll leave the code here pending input from the FSF + on this issue. */ + + if (0 /* && ! NEED_TEMPORARY_P (convfn) Watch out! this macro is undefined */ + && TREE_CODE (expr) == INDIRECT_REF + && TREE_CODE (TREE_TYPE (convfn)) == METHOD_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (convfn))) == REFERENCE_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_TYPE (convfn)))) == RECORD_TYPE + && TREE_TYPE (TREE_TYPE (TREE_TYPE (convfn))) == totype + && TREE_TYPE (expr) == totype) + return 0; + + return 1; +} +/* APPLE LOCAL end direct-binding-refs turly 20020224 */ + /* Initialize a temporary of type TYPE with EXPR. The FLAGS are a bitwise or of LOOKUP_* values. If any errors are warnings are generated, set *DIAGNOSTIC_FN to "error" or "warning", @@ -4172,6 +4200,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, If the target is a class, that means call a ctor. */ if (IS_AGGR_TYPE (totype) + /* APPLE LOCAL direct-binding-refs turly 20020224 */ + && really_call_constructor_p (expr, convfn, totype) && (inner >= 0 || !lvalue_p (expr))) { expr = (build_temp @@ -4812,7 +4842,11 @@ build_over_call (struct z_candidate *cand, int flags) mark_used (fn); - if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0) + /* APPLE LOCAL begin -findirect-virtual-calls 2001-10-30 sts */ + if (DECL_VINDEX (fn) + && (flag_indirect_virtual_calls + || (flags & LOOKUP_NONVIRTUAL) == 0)) + /* APPLE LOCAL end -findirect-virtual-calls 2001-10-30 sts */ { tree t, *p = &TREE_VALUE (converted_args); tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)), @@ -4826,6 +4860,33 @@ build_over_call (struct z_candidate *cand, int flags) t = build_pointer_type (TREE_TYPE (fn)); if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn))) fn = build_java_interface_fn_ref (fn, *p); + /* APPLE LOCAL begin -findirect-virtual-calls 2001-10-30 sts */ + /* If this is not really supposed to be a virtual call, find the + vtable corresponding to the correct type, and use it. */ + else if (flags & LOOKUP_NONVIRTUAL) { + tree call_site_type = TREE_TYPE (cand->access_path); + tree fn_class_type = DECL_CLASS_CONTEXT (fn); + + my_friendly_assert (call_site_type != NULL && + fn_class_type != NULL && + AGGREGATE_TYPE_P (call_site_type) && + AGGREGATE_TYPE_P (fn_class_type), + 20020717); + my_friendly_assert(lookup_base(TYPE_MAIN_VARIANT (call_site_type), + TYPE_MAIN_VARIANT (fn_class_type), + ba_any | ba_quiet, + NULL) != NULL, + 20020719); + + if (TYPE_USES_MULTIPLE_INHERITANCE (call_site_type) + || TYPE_USES_VIRTUAL_BASECLASSES (call_site_type)) + error ("indirect virtual calls are invalid for a type that uses multiple or virtual inheritance"); + + fn = (build_vfn_ref_using_vtable + (BINFO_VTABLE (TYPE_BINFO (call_site_type)), + DECL_VINDEX (fn))); + } + /* APPLE LOCAL end -findirect-virtual-calls 2001-10-30 sts */ else fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn)); TREE_TYPE (fn) = t; diff --git a/gcc/cp/class.c b/gcc/cp/class.c index dca5fe90363..a53548dab62 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -228,6 +228,9 @@ int n_compute_conversion_costs = 0; int n_inner_fields_searched = 0; #endif +/* APPLE LOCAL Macintosh alignment 2002-5-24 ff */ +extern int darwin_align_is_first_member_of_class; + /* Convert to or from a base subobject. EXPR is an expression of type `A' or `A*', an expression of type `B' or `B*' is returned. To convert A to a base B, CODE is PLUS_EXPR and BINFO is the binfo for @@ -452,6 +455,11 @@ build_vtbl_ref_1 (tree instance, tree idx) assemble_external (vtbl); + /* APPLE LOCAL double destructor turly 20020301 */ +#ifdef ADJUST_VTABLE_INDEX + ADJUST_VTABLE_INDEX (idx, vtbl); +#endif + aref = build_array_ref (vtbl, idx); TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx); TREE_INVARIANT (aref) = TREE_CONSTANT (aref); @@ -484,6 +492,30 @@ build_vfn_ref (tree instance, tree idx) return aref; } +/* APPLE LOCAL begin -findirect-virtual-calls 2001-10-30 sts */ +/* Given a VTBL and an IDX, return an expression for the function + pointer located at the indicated index. BASETYPE is the static + type of the object containing the vtable. */ + +tree +build_vfn_ref_using_vtable (tree vtbl, tree idx) +{ + tree aref; + + assemble_external (vtbl); + + /* APPLE LOCAL double destructor turly 20020301 */ +#ifdef ADJUST_VTABLE_INDEX + ADJUST_VTABLE_INDEX (idx, vtbl); +#endif + + aref = build_array_ref (vtbl, idx); + TREE_CONSTANT (aref) = 1; + + return aref; +} +/* APPLE LOCAL end -findirect-virtual-calls 2001-10-30 sts */ + /* Return the name of the virtual function table (as an IDENTIFIER_NODE) for the given TYPE. */ @@ -1778,9 +1810,27 @@ layout_vtable_decl (tree binfo, int n) { tree atype; tree vtable; + /* APPLE LOCAL begin terminated-vtables */ + int n_entries; + + n_entries = n; + + /* Enlarge suggested vtable size by one entry; it will be filled + with a zero word. Darwin kernel dynamic-driver loader looks + for this value to find vtable ends for patching. + + Kludge: IOKit project all use -findirect_virtual_calls, and all + will need the newly-created -fterminated_vtables flag when built + with GCC3, so as a short-term hack to avoid updating + eighty-odd IOKit projects, enable both when we see the one currently + used by all IOKit projects. */ + if (flag_terminated_vtables || flag_indirect_virtual_calls) + n_entries += 1; + /* APPLE LOCAL end terminated-vtables */ atype = build_cplus_array_type (vtable_entry_type, - build_index_type (size_int (n - 1))); + /* APPLE LOCAL terminated-vtables */ + build_index_type (size_int (n_entries - 1))); layout_type (atype); /* We may have to grow the vtable. */ @@ -3830,6 +3880,104 @@ build_clone (tree fn, tree name) return clone; } +/* APPLE LOCAL begin double destructor turly 20020212 */ + +/* Return whether CLASS or any of its ancestors have the + "apple_kext_compatibility" attribute, in which case the non-deleting + destructor is not emitted. + + Note that this only works for single inheritance. */ +int +has_apple_kext_compatibility_attr_p (tree class) +{ + while (class != NULL) + { + if (TYPE_USES_MULTIPLE_INHERITANCE (class)) + return 0; + + if (lookup_attribute ("apple_kext_compatibility", + TYPE_ATTRIBUTES (class))) + return 1; + + /* Multiple inheritance here? Just say no. */ + if (CLASSTYPE_N_BASECLASSES (class) == 1) + class = TYPE_BINFO_BASETYPE (class, 0); + else + break; + } + + return 0; +} + +/* TRUE if we have an operator delete which is empty (i.e., NO CODE!) */ +int +has_empty_operator_delete_p (tree class) +{ + if (class != NULL) + { + if (TYPE_USES_MULTIPLE_INHERITANCE (class)) + return 0; + + if (TYPE_GETS_DELETE (class)) + { + tree f = lookup_fnfields (TYPE_BINFO (class), + ansi_opname (DELETE_EXPR), 0); + + if (f == error_mark_node) + return 0; + + if (BASELINK_P (f)) + f = TREE_VALUE (f); + + if (OVL_CURRENT (f)) + { + f = OVL_CURRENT (f); + + /* We've overridden TREE_SIDE_EFFECTS for C++ operator deletes + to mean that the function is empty. */ + if (TREE_SIDE_EFFECTS (f)) + return 1; + + /* Otherwise, it could be an inline but empty function. */ + if (DECL_SAVED_TREE (f) + && TREE_CODE (DECL_SAVED_TREE (f)) == COMPOUND_STMT + && COMPOUND_BODY (DECL_SAVED_TREE (f))) + return compound_body_is_empty_p (COMPOUND_BODY + (DECL_SAVED_TREE (f))); + } + } + } + + return 0; +} + +/* Walk through a COMPOUND_STMT and return true if nothing in there would + cause us to generate code. */ +int +compound_body_is_empty_p (tree t) +{ + while (t && t != error_mark_node) + { + enum tree_code tc = TREE_CODE (t); + if (tc == COMPOUND_STMT) + { + if (compound_body_is_empty_p (COMPOUND_BODY (t))) + t = TREE_CHAIN (t); + else + return 0; + } + else + if (tc == SCOPE_STMT) + t = TREE_CHAIN (t); + else + return 0; + } + /* We hit the end of the body function without seeing anything. */ + return 1; +} + +/* APPLE LOCAL end double destructor turly 20020212 */ + /* Produce declarations for all appropriate clones of FN. If UPDATE_METHOD_VEC_P is nonzero, the clones are added to the CLASTYPE_METHOD_VEC as well. */ @@ -3874,9 +4022,17 @@ clone_function_decl (tree fn, int update_method_vec_p) if (update_method_vec_p) add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); } - clone = build_clone (fn, complete_dtor_identifier); - if (update_method_vec_p) - add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); + + /* APPLE LOCAL double destructor turly 20020212 */ + /* Don't use the complete dtor. */ + if (! flag_apple_kext + || ! has_apple_kext_compatibility_attr_p (DECL_CONTEXT (fn))) + { + clone = build_clone (fn, complete_dtor_identifier); + if (update_method_vec_p) + add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); + } + clone = build_clone (fn, base_dtor_identifier); if (update_method_vec_p) add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0); @@ -4593,6 +4749,13 @@ layout_class_type (tree t, tree *virtuals_p) NULL, NULL); build_base_fields (rli, empty_base_offsets, next_field); + /* APPLE LOCAL begin Macintosh alignment 2002-5-24 ff */ + /* Turn on this flag until the first real member of the class is + laid out. (Enums and such things declared in the class do not + count.) */ + darwin_align_is_first_member_of_class = 1; + /* APPLE LOCAL end Macintosh alignment 2002-5-24 ff */ + /* Layout the non-static data members. */ for (field = non_static_data_members; field; field = TREE_CHAIN (field)) { @@ -4705,6 +4868,12 @@ layout_class_type (tree t, tree *virtuals_p) layout_nonempty_base_or_field (rli, field, NULL_TREE, empty_base_offsets); + /* APPLE LOCAL begin Macintosh alignment 2002-5-24 ff */ + /* When we reach here we have laid out the first real member of + the class. */ + darwin_align_is_first_member_of_class = 0; + /* APPLE LOCAL end Macintosh alignment 2002-5-24 ff */ + /* Remember the location of any empty classes in FIELD. */ if (abi_version_at_least (2)) record_subobject_offsets (TREE_TYPE (field), @@ -4756,6 +4925,12 @@ layout_class_type (tree t, tree *virtuals_p) last_field_was_bitfield = DECL_C_BIT_FIELD (field); } + /* APPLE LOCAL begin Macintosh alignment 2002-5-24 ff */ + /* Make sure the flag is turned off in cases where there were no + real members in the class. */ + darwin_align_is_first_member_of_class = 0; + + /* APPLE LOCAL end Macintosh alignment 2002-5-24 ff */ if (abi_version_at_least (2) && !integer_zerop (rli->bitpos)) { /* Make sure that we are on a byte boundary so that the size of @@ -5609,6 +5784,15 @@ push_lang_context (tree name) { current_lang_name = name; } + /* APPLE LOCAL begin Objective-C++ */ + else if (name == lang_name_objc) + { + /* Suppress the warning for now, make it informative. */ + inform ("`extern \"Objective-C\"' is deprecated; " + "use `extern \"C\"' instead"); + current_lang_name = lang_name_c; + } + /* APPLE LOCAL end Objective-C++ */ else error ("language string `\"%s\"' not recognized", IDENTIFIER_POINTER (name)); } @@ -7203,6 +7387,19 @@ dfs_accumulate_vtbl_inits (tree binfo, index = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (vtable_entry_type), index); + /* APPLE LOCAL begin double destructor turly 20020301 */ +#ifdef VPTR_INITIALIZER_ADJUSTMENT + /* Subtract VPTR_INITIALIZER_ADJUSTMENT from INDEX. */ + if (flag_apple_kext && !ctor_vtbl_p && ! BINFO_PRIMARY_P (binfo) + && TREE_CODE (index) == INTEGER_CST + && TREE_INT_CST_LOW (index) >= VPTR_INITIALIZER_ADJUSTMENT + && TREE_INT_CST_HIGH (index) == 0) + index = fold (build (MINUS_EXPR, + TREE_TYPE (index), index, + size_int (VPTR_INITIALIZER_ADJUSTMENT))); +#endif + /* APPLE LOCAL end double destructor turly 20020301 */ + vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index); } diff --git a/gcc/cp/cp-dmp-tree.c b/gcc/cp/cp-dmp-tree.c new file mode 100644 index 00000000000..3827e3d7fbd --- /dev/null +++ b/gcc/cp/cp-dmp-tree.c @@ -0,0 +1,1326 @@ +/* APPLE LOCAL file new tree dump */ +/* Common condensed c++ tree display routines. Based on dmp-tree.c + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Devang Patel (dpatel@apple.com) + and Ira L. Ruben (ira@apple.com) + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Both C and C++ node handling is required for C++. The C handling is + done in c-dmp-tree.c. But that is a C language specific file, i.e., + only built for C. Thus we need to #include it here to get the stuff + we need defined. But we need to tell c-dmp-tree.c that we are doing + this so it doesn't define stuff we don't want defined. That's the + purpose of the CP_DMP_TREE switch. + + Note that c-dmp-tree.c does all the main #includes so we don't need + them here. */ + +#define CP_DMP_TREE +#include "c-dmp-tree.c" + +#include "cp-tree.h" + +int cp_dump_tree_p (FILE *, const char *, tree, int); +lang_dump_tree_p_t cp_prev_lang_dump_tree_p = NULL; + +#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) \ +static void print_ ## SYM (FILE *file, const char *annotation, tree node, int indent); +#include "cp-tree.def" +#undef DEFTREECODE + +static void print_RECORD_TYPE (FILE *, const char *, tree, int); +static void print_NAMESPACE_DECL (FILE *, const char *, tree, int); +static void print_ADDR_EXPR (FILE *, const char *, tree, int); + +/*-------------------------------------------------------------------*/ + +/* Called twice for dmp-tree() for an IDENTIFIER_NODE. The first call + is after the common info for the node is generated but before + displaying the identifer (before_id==0) which is always assumed + to be the last thing on the line. + + The second call is done after the id is displayed (before_id!=0). + This is for displaying any language-specific node information that + should be preceded by an newline_and_indent() call or a recursive + call to dump_tree() for nodes which are language specific operands + to a IDENTIFIER_NODE. */ + +void +cxx_dump_identifier (FILE *file, + tree node, + int indent ATTRIBUTE_UNUSED, + int after_id) +{ + if (!after_id) + { + if (C_IS_RESERVED_WORD (node)) + fputs (" reserved", file); + if (IDENTIFIER_CTOR_OR_DTOR_P (node)) + fputs (" ctor/dtor", file); + if (IDENTIFIER_NAMESPACE_BINDINGS (node)) + { + fprintf (file, " ns-bindings="); + fprintf (file, HOST_PTR_PRINTF, IDENTIFIER_NAMESPACE_BINDINGS (node)); + } + if (IDENTIFIER_CLASS_VALUE (node)) + { + fprintf (file, " binding="); + fprintf (file, HOST_PTR_PRINTF, IDENTIFIER_CLASS_VALUE (node)); + } + if (IDENTIFIER_BINDING (node)) + { + fprintf (file, " lcl-bindings="); + fprintf (file, HOST_PTR_PRINTF, IDENTIFIER_BINDING (node)); + } + if (IDENTIFIER_LABEL_VALUE (node)) + { + fprintf (file, " gbl="); + fprintf (file, HOST_PTR_PRINTF, IDENTIFIER_LABEL_VALUE (node)); + } + if (IDENTIFIER_TEMPLATE (node)) + { + fprintf (file, " tmpl="); + fprintf (file, HOST_PTR_PRINTF, IDENTIFIER_TEMPLATE (node)); + } + if (IDENTIFIER_IMPLICIT_DECL (node)) + { + fprintf (file, " impl="); + fprintf (file, HOST_PTR_PRINTF, IDENTIFIER_IMPLICIT_DECL (node)); + } + if (IDENTIFIER_ERROR_LOCUS (node)) + { + fprintf (file, " err-locus="); + fprintf (file, HOST_PTR_PRINTF, IDENTIFIER_ERROR_LOCUS (node)); + } + } + else + { +#if 0 + dump_binding (file, "(bindings)", IDENTIFIER_NAMESPACE_BINDINGS (node), indent + INDENT); +#endif + dump_tree (file, "(class)", IDENTIFIER_CLASS_VALUE (node), indent + INDENT); +#if 0 + dump_binding (file, "(lcl-bindings)", IDENTIFIER_BINDING (node), indent + INDENT); +#endif + dump_tree (file, "(lbl)", IDENTIFIER_LABEL_VALUE (node), indent + INDENT); + dump_tree (file, "(tmpl)", IDENTIFIER_TEMPLATE (node), indent + INDENT); + dump_tree (file, "(impl)", IDENTIFIER_IMPLICIT_DECL (node), indent + INDENT); + dump_tree (file, "(err-locus)", IDENTIFIER_ERROR_LOCUS (node), indent + INDENT); + } +} + +/* Called twice for dmp_tree() for a ..._DECL node. The first call + after the common info for the node is generated but before + displaying the identifier (before_id==0) which is always assumed + to be the last thing on the line. + + The second call is done after the id is displayed (before_id!=0). + This is for displaying any language-specific node information that + should be preceded by an newline_and_indent() call or a recursive + call to dump_tree() for nodes which are language specific operands + to a ..._DECL node. */ + +void +cxx_dump_decl (FILE *file, tree node, int indent ATTRIBUTE_UNUSED, int after_id) +{ + switch (TREE_CODE (node)) + { + case FUNCTION_DECL: + if (!after_id) + { + if (DECL_STATIC_FUNCTION_P (node)) + fputs (" static", file); + if (DECL_FRIEND_P (node)) + fputs (" frnd", file); + if (DECL_CONSTRUCTOR_P (node)) + fprintf (file, " %sctor", + DECL_COPY_CONSTRUCTOR_P (node) ? "cpy-" : ""); + if (DECL_DESTRUCTOR_P (node)) + fputs (" dtor", file); + if (DECL_PURE_VIRTUAL_P (node)) + fputs (" pure-virt", file); + if (DECL_CONST_MEMFUNC_P (node)) + fputs (" const", file); + if (DECL_VOLATILE_MEMFUNC_P (node)) + fputs (" volatile", file); + if (DECL_MUTABLE_P (node)) + fputs (" mutable", file); + if (DECL_THUNK_P (node)) + fputs (" thnk", file); + if (DECL_LANG_SPECIFIC (node)) + { + if (DECL_PENDING_INLINE_INFO (node)) + { + fprintf (file, " pending-inline-info="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_PENDING_INLINE_INFO (node))); + } + if (DECL_TEMPLATE_INFO (node)) + { + fprintf (file, " tmpl-info="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_TEMPLATE_INFO (node))); + } + } + } + break; + + case FIELD_DECL: + if (!after_id) + { + if (DECL_MUTABLE_P (node)) + fputs (" mutable", file); + } + break; + + case TYPE_DECL: + if (!after_id) + { + if (DECL_LANG_SPECIFIC (node)) + { + if (DECL_TEMPLATE_INFO (node)) + { + fprintf (file, " tmpl-info="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_TEMPLATE_INFO (node))); + } + if (DECL_SORTED_FIELDS (node)) + { + fprintf (file, " sorted-fields="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_SORTED_FIELDS (node))); + } + } + } + break; + + case VAR_DECL: + if (!after_id) + { + if (DECL_LANG_SPECIFIC (node)) + { + if (DECL_TEMPLATE_INFO (node)) + { + fprintf (file, " tmpl-info="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_TEMPLATE_INFO (node))); + } + } + if (DECL_SHADOWED_FOR_VAR (node)) + fputs (" shadowed", file); + } + break; + + default: + break; + } +} + +/* Called twice for dmp_tree() for a ..._TYPE node. The first call + after the common info for the node is generated but before + displaying the identifier (before_id==0) which is always assumed + to be the last thing on the line. + + The second call is done after the id is displayed (before_id!=0). + This is for displaying any language-specific node information that + should be preceded by an newline_and_indent() call or a recursive + call to dump_tree() for nodes which are language specific operands + to a ..._TYPE node. */ + +void +cxx_dump_type (FILE *file, tree node, int indent, int after_id) +{ + if (!after_id) + { + if (CLASS_TYPE_P (node)) /* RECORD_TYPE, UNION_TYPE only */ + { + if (TYPE_NEEDS_CONSTRUCTING (node)) + fputs (" needs-ctor", file); + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (node)) + fputs (" needs-dtor", file); + if (TYPE_HAS_DESTRUCTOR (node)) + fputs (" ~X()", file); + if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node)) + fputs (" X()", file); + if (TYPE_HAS_CONVERSION (node)) + fputs (" has-conv", file); + if (TYPE_HAS_INIT_REF (node)) + { + if (TYPE_HAS_CONST_INIT_REF (node)) + fputs (" X(constX&)", file); + else + fputs (" X(X&)", file); + } + if (TYPE_HAS_NEW_OPERATOR (node)) + fputs (" new", file); + if (TYPE_HAS_ARRAY_NEW_OPERATOR (node)) + fputs (" new[]", file); + if (TYPE_GETS_DELETE (node) & 1) + fputs (" delete", file); + if (TYPE_GETS_DELETE (node) & 2) + fputs (" delete[]", file); + if (TYPE_HAS_ASSIGN_REF (node)) + fputs (" this=(X&)", file); + if (TYPE_USES_MULTIPLE_INHERITANCE (node)) + fputs (" uses-mult-inh", file); + } + } + + switch (TREE_CODE (node)) + { + case FUNCTION_TYPE: + case METHOD_TYPE: + if (!after_id) + { + if (TYPE_RAISES_EXCEPTIONS (node)) + { + fprintf (file, " throws="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_RAISES_EXCEPTIONS (node))); + } + } + else + { + if (TYPE_RAISES_EXCEPTIONS (node)) + dump_tree (file, "(throws)", TYPE_RAISES_EXCEPTIONS (node), + indent + INDENT); + } + break; + + default: + break; + } +} + +/* Normally a blank line is inserted before each statement node (a + statement node is determined by calling statement_code_p()). This + makes the display easier to read by keeping each statement grouped + like a paragraph. There may, however, be some kinds of statements + where a blank line isn't desired (e.g., a begin SCOPE_STMT in C). + Thus dump_lang_blank_line() is called to ask if a particular + statement should be preceded by a blank line dependent upon the + node that preceded it. + + dump_lang_blank_line_p() is called for each statement passing the + previous node (not necessarily a statement) and current node (a + statement node by definition). It should return 1 if a blank + line is to be inserted and 0 otherwise. */ + +int +cxx_dump_blank_line_p (tree previous_node ATTRIBUTE_UNUSED, + tree current_node ATTRIBUTE_UNUSED) +{ + return 1; +} + +/* This is called for each node to display file and/or line number + information for those nodes that have such information. If it + is displayed the function should return 1. If not, 0. + + The function generally does not have to handle ..._DECL nodes + unless there some special handling is reequired. They are + handled by print_lineno() (dump_lang_lineno_p()'s caller). + It is defined to not repeat the filename if it does not + change from what's in dump_tree_state.curr_file and then + it only displays the basename (using lbasename()). The + format of the display is " line=nbr(basename)" where the + leading space is included as usual in these displays and + the parenthesized basename omitted if not needed or is + the same as before. */ + +int +cxx_dump_lineno_p (FILE *file ATTRIBUTE_UNUSED, tree node ATTRIBUTE_UNUSED) +{ + return 0; +} + +/* Called only by tree-dump.c when doing a full compilation tree dump + under one of the -fdmp-xxxx options. This makes tree_dump.c, which + is common to all languages, independent of dmp_tree, which currently + only supports the c languages. */ +int +cxx_dmp_tree3 (file, node, flags) + FILE *file; + tree node; + int flags; +{ + dmp_tree3 (file, node, flags); + return 1; +} + +/*-------------------------------------------------------------------*/ + +static void +print_OFFSET_REF (FILE *file, const char *annotation, tree node, int indent) +{ + if (PTRMEM_OK_P (node)) + fputs (" ptr-to-mbr-ok", file); + print_ref (file, annotation, node, indent); + + print_operands (file, node, indent, TRUE, "(obj)", "(offset)", NULL); +} + +static void +print_NON_DEPENDENT_EXPR (FILE *file, const char *annotation, tree node, + int indent) +{ +} + +static void +print_PTRMEM_CST (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent ATTRIBUTE_UNUSED) +{ + fprintf (file, " rec-type::mbr-decl="); + fprintf (file, HOST_PTR_PRINTF, HOST_PTR_PRINTF_VALUE (PTRMEM_CST_CLASS (node))); + fprintf (file, "::"); + fprintf (file, HOST_PTR_PRINTF, HOST_PTR_PRINTF_VALUE (PTRMEM_CST_MEMBER (node))); + /* not sure I want to follow these nodes here */ +} + +static void +print_NEW_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + if (NEW_EXPR_USE_GLOBAL (node)) + fputs ("use-glbl", file); + + print_operands (file, node, indent, TRUE, "(placement)", "(new)", "(init)", NULL); +} + +static void +print_VEC_NEW_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(placement)", "(new)", "(init)", NULL); +} + +static void +print_DELETE_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + if (DELETE_EXPR_USE_GLOBAL (node)) + fputs ("use-glbl", file); + if (DELETE_EXPR_USE_VEC (node)) + fputs ("use-vec", file); + + print_operands (file, node, indent, TRUE, "(store)", "(how)", NULL); +} + +static void +print_VEC_DELETE_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(store)", "(how)", NULL); +} + +static void +print_SCOPE_REF (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_ref (file, annotation, node, indent); + fprintf (file, " complexity=%d", TREE_COMPLEXITY (node)); + + print_operands (file, node, indent, TRUE, "(class)", "(field)", NULL); +} + +static void +print_MEMBER_REF (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_ref (file, annotation, node, indent); + + print_operands (file, node, indent, FALSE, "(obj)", "(mbr)", NULL); + /* not sure I want to follow these nodes here */ +} + +static void +print_TYPE_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + fprintf (file, " type="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_TYPE (node))); + + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_AGGR_INIT_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + if (AGGR_INIT_VIA_CTOR_P(node)) + fputs (" ctor", file); + + print_operands (file, node, indent, TRUE, "(init-funct)", "(args)", "(slot)", NULL); +} + +static void +print_THROW_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_EMPTY_CLASS_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent ATTRIBUTE_UNUSED) +{ + if (TREE_TYPE (node)) + { + fprintf (file, "class="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_TYPE (node))); + } +} + +static void +print_BASELINK (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_TEMPLATE_DECL (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + dump_tree_state.line_cnt = 0; + + fprintf (file, " args="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_ARGUMENTS (node))); + if (DECL_LANG_SPECIFIC (node) && DECL_TEMPLATE_INFO (node)) + { + fprintf (file, " tmpl-info="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_TEMPLATE_INFO (node))); + } + if (DECL_VINDEX (node)) + { + fprintf (file, " inst="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_VINDEX (node))); + } + if (TREE_TYPE (node)) + { + fprintf (file, " obj-type="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_TYPE (node))); + } + if (DECL_TEMPLATE_RESULT (node)) + { + fprintf (file, " obj-decl="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_TEMPLATE_RESULT (node))); + } + if (DECL_INITIAL (node)) + { + fprintf (file, " assoc-tmpls="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_INITIAL (node))); + } + print_decl (file, annotation, node, indent); + (void)node_seen (node, TRUE); + + if (DECL_ARGUMENTS (node)) + { + if (dump_tree_state.line_cnt > 1) + newline_and_indent (file, 0); + dump_tree (file, "(args)", DECL_ARGUMENTS (node), indent + INDENT); + } + + if (DECL_VINDEX (node)) + { + if (dump_tree_state.line_cnt > 1) + newline_and_indent (file, 0); + dump_tree (file, "(inst)", DECL_VINDEX (node), indent + INDENT); + } + + /* tsubst_decl() in cp/pt.c looks interesting */ + if (TREE_TYPE (node)) + { + if (dump_tree_state.line_cnt > 1) + newline_and_indent (file, 0); + dump_tree (file, "(obj-type)", TREE_TYPE (node), indent + INDENT); + } + + if (DECL_TEMPLATE_RESULT (node)) + { + if (dump_tree_state.line_cnt > 1) + newline_and_indent (file, 0); + dump_tree (file, "(obj-decl)", DECL_TEMPLATE_RESULT (node), indent + INDENT); + } + + if (DECL_INITIAL (node)) + { + if (dump_tree_state.line_cnt > 1) + newline_and_indent (file, 0); + dump_tree (file, "(assoc-tmpl)", DECL_INITIAL (node), indent + INDENT); + } +} + +static void +print_TEMPLATE_PARM_INDEX (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + fprintf (file, " idx/lvl=("HOST_WIDE_INT_PRINT_DEC","HOST_WIDE_INT_PRINT_DEC")" + " orig-lvl="HOST_WIDE_INT_PRINT_DEC + " dcndnts=", + TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL(node), + TEMPLATE_PARM_ORIG_LEVEL (node)); + fprintf (file, HOST_PTR_PRINTF, HOST_PTR_PRINTF_VALUE (TEMPLATE_PARM_DESCENDANTS (node))); + + + print_decl (file, annotation, TEMPLATE_PARM_DECL(node), indent + INDENT); + dump_tree (file, "(dcndnt)", TEMPLATE_PARM_DESCENDANTS (node), indent + INDENT); +} + +static void +print_TEMPLATE_TYPE_PARM (FILE *file, + const char *annotation, + tree node, + int indent) +{ + fprintf (file, " parms="); + fprintf (file, HOST_PTR_PRINTF, HOST_PTR_PRINTF_VALUE (TEMPLATE_TYPE_IDX (node))); + fprintf (file, " idx/lvl=("HOST_WIDE_INT_PRINT_DEC","HOST_WIDE_INT_PRINT_DEC")" + " orig-lvl="HOST_WIDE_INT_PRINT_DEC, + TEMPLATE_TYPE_IDX (node), TEMPLATE_TYPE_LEVEL (node), + TEMPLATE_TYPE_ORIG_LEVEL (node)); + print_type (file, annotation, node, indent); + + dump_tree (file, "(parm)", TEMPLATE_TYPE_PARM_INDEX (node), indent + INDENT); +} + +static void +print_TEMPLATE_TEMPLATE_PARM (FILE *file, + const char *annotation, + tree node, + int indent) +{ + fprintf (file, " tmpl-decl="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_NAME (node))); + + print_TEMPLATE_TYPE_PARM (file, annotation, node, indent); + + dump_tree (file, "(tmpl-decl)", TYPE_NAME (node), indent + INDENT); +} + +static void +print_BOUND_TEMPLATE_TEMPLATE_PARM (FILE *file, + const char *annotation, + tree node, + int indent) +{ + fprintf (file, " name="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (node))); + fprintf (file, " type-decl="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_NAME (node))); + fprintf (file, " tmpl-decl="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_TI_TEMPLATE (node))); + + print_TEMPLATE_TYPE_PARM (file, annotation, node, indent); + + dump_tree (file, "(name)", TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (node), indent + INDENT); + dump_tree (file, "(type-decl)", TYPE_NAME (node), indent + INDENT); + dump_tree (file, "(tmpl-decl)", TYPE_TI_TEMPLATE (node), indent + INDENT); +} + +static void +print_TYPENAME_TYPE (FILE *file, + const char *annotation, + tree node, + int indent) +{ + fprintf (file, " cntxt::id="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_CONTEXT (node))); + fprintf (file, "::"); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_NAME (node))); + + if (TYPENAME_TYPE_FULLNAME (node)) + { + fprintf (file, " fullname="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPENAME_TYPE_FULLNAME (node))); + } + if (TREE_TYPE (node)) + { + fprintf (file, " impl-type="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_TYPE (node))); + } + print_type (file, annotation, node, indent); + + dump_tree (file, "(cntxt)", TYPE_CONTEXT (node), indent + INDENT); + dump_tree (file, "(id)", TYPE_NAME (node), indent + INDENT); + dump_tree (file, "(fullname)", TYPENAME_TYPE_FULLNAME (node), indent + INDENT); + dump_tree (file, "(impl-type)", TREE_TYPE (node), indent + INDENT); +} + +static void +print_UNBOUND_CLASS_TEMPLATE (FILE *file, + const char *annotation, + tree node, + int indent) +{ + fprintf (file, " cntxt::id="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_CONTEXT (node))); + fprintf (file, "::"); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_NAME (node))); + print_type (file, annotation, node, indent); + + dump_tree (file, "(cntxt)", TYPE_CONTEXT (node), indent + INDENT); + dump_tree (file, "(id)", TYPE_NAME (node), indent + INDENT); +} + +static void +print_TYPEOF_TYPE (FILE *file, + const char *annotation, + tree node, + int indent) +{ + fprintf (file, " "); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_FIELDS (node))); + print_type (file, annotation, node, indent); + + dump_tree (file, NULL, TYPE_FIELDS (node), indent + INDENT); +} + +static void +print_USING_DECL (FILE *file, + const char *annotation, + tree node, + int indent) +{ + fprintf (file, " scope="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_INITIAL (node))); + print_decl (file, annotation, node, indent); + + dump_tree (file, "(scope)", DECL_INITIAL (node), indent + INDENT); +} + +static void +print_USING_STMT (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(using)", NULL); +} + +static void +print_DEFAULT_ARG (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent ATTRIBUTE_UNUSED) +{ +#if 0 + /* TO DO */ + fprintf (file, " def-arg="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DEFARG_POINTER (node))); +#endif + fprintf (file, " (struct unparsed_text * in cp/spew.c)"); + + if (TREE_PURPOSE (node)) + { + fprintf (file, " purpose="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_PURPOSE (node))); + dump_tree (file, "(purpose)", TREE_PURPOSE (node), indent + INDENT); + } +} + +static void +print_TEMPLATE_ID_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(tmpl)", "(args)", NULL); +} + +#if 0 + +static void +print_CPLUS_BINDING (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + tree n; + + #define BINDING_LEVEL(NODE) \ + (((struct tree_binding*)NODE)->scope.level) + + if (LOCAL_BINDING_P (node)) + fputs (" local", file); + if (INHERITED_VALUE_BINDING_P (node)) + fputs (" inherited", file); + + fprintf (file, " value="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (BINDING_VALUE (node))); + + if (BINDING_HAS_LEVEL_P (node)) + { + fprintf (file, " level="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE ( (node))); + fprintf (file, " (struct binding_level * in cp/decl.c)"); + } + else + { + fprintf (file, " scope="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (BINDING_LEVEL (node))); + } + + if (TREE_CHAIN (node)) + { + fprintf (file, " chain="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_CHAIN (node))); + } + + dump_tree (file, "(value)", BINDING_VALUE (node), indent + INDENT); + if (!BINDING_HAS_LEVEL_P (node)) + dump_tree (file, "(scope)", BINDING_SCOPE (node), indent + INDENT); + + for (n = TREE_CHAIN (node); n; n = TREE_CHAIN (n)) + dump_tree (file, "(chain)", n, indent + INDENT); +} + +#endif + +static void +print_OVERLOAD (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + tree n; + + if (OVL_FUNCTION (node)) + { + fprintf (file, " ovld="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (OVL_FUNCTION (node))); + } + if (OVL_CHAIN (node)) + { + fprintf (file, " next-ovld="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (OVL_CHAIN (node))); + } + + if ((TREE_CODE (OVL_FUNCTION (node)) == FUNCTION_DECL + || TREE_CODE (OVL_FUNCTION (node)) == TEMPLATE_DECL) + && DECL_NAME (OVL_FUNCTION (node))) + fprintf (file, " %s", + IDENTIFIER_POINTER (DECL_NAME (OVL_FUNCTION (node)))); + + if (DECL_CONSTRUCTOR_P (OVL_FUNCTION (node))) + dump_tree (file, NULL, OVL_FUNCTION (node), indent + INDENT); + else + dump_tree (file, "(ovld)", OVL_FUNCTION (node), indent + INDENT); + + for (n = OVL_CHAIN (node); n; n = OVL_CHAIN (n)) + dump_tree (file, NULL, n, indent + INDENT); +} + +static void +print_WRAPPER (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent ATTRIBUTE_UNUSED) +{ + /* TODO: Print out tree_common. */ + fprintf (file, " ptr="); + fprintf (file, HOST_PTR_PRINTF, HOST_PTR_PRINTF_VALUE (WRAPPER_ZC (node))); +} + +static void +print_MODOP_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(lhs)", "(modifycode)", "(rhs)", NULL); +} + +static void +print_CAST_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_REINTERPRET_CAST_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_CONST_CAST_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_STATIC_CAST_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_DYNAMIC_CAST_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node ATTRIBUTE_UNUSED, + int indent ATTRIBUTE_UNUSED) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_DOTSTAR_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(datum)", "(cmpnt)", NULL); +} + +static void +print_TYPEID_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_PSEUDO_DTOR_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(obj)", "(scope)", "(dtor)", NULL); +} + +static void +print_CTOR_INITIALIZER (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(mbr-init)", "(base-init)", NULL); +} + +#if 0 +static void +print_RETURN_INIT (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(id)", "(init)", NULL); +} +#endif + +static void +print_TRY_BLOCK (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + if (FN_TRY_BLOCK_P (node)) + fputs (" func-try-blk", file); + if (CLEANUP_P (node)) + fputs (" clnup", file); + + print_operands (file, node, indent, TRUE, "(body)", "(hndlrs)", NULL); +} + +static void +print_EH_SPEC_BLOCK (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, "(body)", "(raises)", NULL); +} + +static void +print_HANDLER (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + fprintf (file, " hdnlr-type="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (HANDLER_TYPE (node))); + + print_operands (file, node, indent, TRUE, "(parms)", "(body)", NULL); +} + +static void +print_MUST_NOT_THROW_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_TAG_DEFN (FILE *file ATTRIBUTE_UNUSED, + const char *annotation ATTRIBUTE_UNUSED, + tree node ATTRIBUTE_UNUSED, + int indent ATTRIBUTE_UNUSED) +{ +} + +static void +print_IDENTITY_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_LVALUE_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_QUAL_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_STD_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_PTR_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_PMEM_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_BASE_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_REF_BIND (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_USER_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + fprintf (file, " from="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_OPERAND (node, 0))); + fprintf (file, " cand="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TREE_OPERAND (node, 1))); + + print_operands (file, node, indent, TRUE, "(from)", "(cand)", NULL); +} + +static void +print_AMBIG_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_RVALUE_CONV (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + print_operands (file, node, indent, TRUE, NULL); +} + +/*-------------------------------------------------------------------*/ + +/* Override to routine in dmp-tree.c print Method vector Record Type. */ +static void +print_RECORD_TYPE (FILE *file, + const char *annotation, + tree node, + int indent) +{ + tree n; + + fprintf (file, " fields="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_FIELDS (node))); + fprintf (file, " mbrs="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (CLASSTYPE_METHOD_VEC (node))); + if (TYPE_NO_FORCE_BLK (node)) + fputs (" no-force-blk", file); + fprintf (file, " #parents=%d", CLASSTYPE_N_BASECLASSES (node)); + if (CLASSTYPE_USE_TEMPLATE (node)) + fprintf (file, " use-tmpl=%d", CLASSTYPE_USE_TEMPLATE (node)); + if (TYPE_PTRMEMFUNC_P (node)) + { + fprintf (file, " ptrmemfunc-fn-type="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (TYPE_PTRMEMFUNC_FN_TYPE (node))); + } + print_type (file, annotation, node, indent); + (void)node_seen (node, TRUE); + + for (n = TYPE_FIELDS (node); n; n = TREE_CHAIN (n)) + { + if (TREE_CODE (n) == TYPE_DECL + && TREE_TYPE (n) == DECL_CONTEXT (n) + && TREE_TYPE (n) == node) + dump_tree (file, "(self-reference)", n, indent + INDENT); + else + dump_tree (file, NULL, n, indent + INDENT); + } + + dump_tree (file, "(mbrs)", CLASSTYPE_METHOD_VEC (node), indent + INDENT); + + if (TYPE_PTRMEMFUNC_P (node)) + { + newline_and_indent (file, 0); + dump_tree (file, "(ptrmemfunc-fn-type)", + TYPE_PTRMEMFUNC_FN_TYPE (node), indent + INDENT); + } +} + +/* Override to routine in dmp-tree.c to print namespace. */ +static void +print_NAMESPACE_DECL (FILE *file, + const char *annotation, + tree node, + int indent) +{ + if (NAMESPACE_LEVEL (node)) + { + fprintf (file, " binding_lvl="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (NAMESPACE_LEVEL (node))); + } + if (DECL_NAMESPACE_ALIAS (node)) + { + fprintf (file, " alias="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_NAMESPACE_ALIAS (node))); + } + if (DECL_NAMESPACE_USING (node)) + { + fprintf (file, " using="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_NAMESPACE_USING (node))); + } + if (DECL_NAMESPACE_USERS (node)) + { + fprintf (file, " usrs="); + fprintf (file, HOST_PTR_PRINTF, + HOST_PTR_PRINTF_VALUE (DECL_NAMESPACE_USERS (node))); + } + + print_decl (file, annotation, node, indent); + + dump_tree (file, "(alias)", DECL_NAMESPACE_ALIAS (node), indent + INDENT); + dump_tree (file, "(using)", DECL_NAMESPACE_USING (node), indent + INDENT); + dump_tree (file, "(usrs)", DECL_NAMESPACE_USERS (node), indent + INDENT); + + if (dump_tree_state.visit_only_once == DMP_TREE_VISIT_ONCE2) + { + for (node = cp_namespace_decls (node); node; node = TREE_CHAIN (node)) + dump_tree (file, NULL, node, indent + INDENT); + } +} + +static void +print_ADDR_EXPR (FILE *file, + const char *annotation ATTRIBUTE_UNUSED, + tree node, + int indent) +{ + if (PTRMEM_OK_P (node)) + fputs (" ptr-to-mbr-ok", file); + + print_operands (file, node, indent, TRUE, NULL); +} + +static void +print_ALIAS_DECL (FILE *file ATTRIBUTE_UNUSED, + const char *annotation ATTRIBUTE_UNUSED, + tree node ATTRIBUTE_UNUSED, + int indent ATTRIBUTE_UNUSED) +{ + /* TO DO */ +} + +/*-------------------------------------------------------------------*/ + +/* Return 1 if tree node is a C++ specific tree node from cp-tree.def + or a tree node specific to whatever cp_prev_lang_dump_tree_p + calls. Otherwise return 0. +*/ + +int +cp_dump_tree_p (FILE *file, const char *annotation, tree node, int indent) +{ + switch (TREE_CODE (node)) + { + #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) \ + case SYM: print_ ## SYM (file, annotation, node, indent); break; + #include "cp-tree.def" + #undef DEFTREECODE + + case RECORD_TYPE: + print_RECORD_TYPE (file, annotation, node, indent); + break; + + case NAMESPACE_DECL: + print_NAMESPACE_DECL (file, annotation, node, indent); + break; + + case ADDR_EXPR: + print_ADDR_EXPR (file, annotation, node, indent); + break; + + default: + return cp_prev_lang_dump_tree_p (file, annotation, node, indent); + break; + } + + return 1; +} + +/*-------------------------------------------------------------------*/ + +#if 0 + +cd $gcc3/gcc; \ +cc -no-cpp-precomp -c -DIN_GCC -g \ + -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \ + -DHAVE_CONFIG_H \ + -I$gcc3obj \ + -Icp \ + -I. \ + -Iconfig \ + -I../include \ + cp/cp-dmp-tree.c -o ~/tmp.o -w + +#endif diff --git a/gcc/cp/cp-idebug.c b/gcc/cp/cp-idebug.c new file mode 100644 index 00000000000..1ed38930881 --- /dev/null +++ b/gcc/cp/cp-idebug.c @@ -0,0 +1,463 @@ +/* APPLE LOCAL file debugging */ +/* C++ tree & rtl accessors defined as functions for use in a debugger. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Ira L. Ruben (ira@apple.com) + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* What we do here is to instantiate each macro as a function *BY + THE SAME NAME*. Depends on the macro not being expanded when + it is surrounded by parens. + + Note that this file includes idebug.c so that only debugging + macros for cp-tree.h are actually defined here. For C++ only + this file is included in the link while for C only c-idebug.c + is built and included in the link. */ + +#include "idebug.c" + +#ifdef ENABLE_IDEBUG + +#include "cp/cp-tree.h" + +/* C++ tree debugging macro functions. From cp-tree.h. + I made special-case meta-macros for the most common + one-parameter ones, that take a node and return either + a node or an int. */ + +#define fn_noden( m ) fn_1(m, tree, tree) +#define fn_nodei( m ) fn_1(m, int, tree) + +/* Macros from cp-tree.h */ + +fn_nodei( C_IS_RESERVED_WORD ) +fn_1( C_RID_CODE, enum rid, struct lang_identifier * ) +fn_1( LANG_IDENTIFIER_CAST, struct lang_identifier *, tree ) +fn_noden( BINDING_SCOPE ) +fn_nodei( BINDING_HAS_LEVEL_P ) +fn_noden( BINDING_VALUE ) +fn_noden( BINDING_TYPE ) +fn_noden( IDENTIFIER_GLOBAL_VALUE ) +fn_noden( IDENTIFIER_NAMESPACE_VALUE ) +fn_nodei( CLEANUP_P ) +fn_noden( CLEANUP_DECL ) +fn_noden( CLEANUP_EXPR ) +fn_2( same_type_p, int, tree, tree ) +fn_2( same_type_ignoring_top_level_qualifiers_p, int, tree, tree ) +fn_nodei( DECL_MAIN_P ) +fn_noden( OVL_FUNCTION ) +fn_noden( OVL_CHAIN ) +fn_noden( OVL_CURRENT ) +fn_noden( OVL_NEXT ) +fn_nodei( OVL_USED ) +fn_nodei( BASELINK_P ) +fn_nodei( SET_BASELINK_P ) +fn_1( SRCLOC_FILE, const char *, tree ) +fn_nodei( SRCLOC_LINE ) +fn_noden( IDENTIFIER_NAMESPACE_BINDINGS ) +fn_noden( IDENTIFIER_TEMPLATE ) +fn_noden( IDENTIFIER_BINDING ) +fn_noden( IDENTIFIER_VALUE ) +fn_noden( IDENTIFIER_CLASS_VALUE ) +fn_noden( IDENTIFIER_TYPE_VALUE ) +fn_noden( REAL_IDENTIFIER_TYPE_VALUE ) +fn_nodei( IDENTIFIER_HAS_TYPE_VALUE ) +fn_noden( IDENTIFIER_LABEL_VALUE ) +fn_noden( IDENTIFIER_IMPLICIT_DECL ) +fn_noden( IDENTIFIER_ERROR_LOCUS ) +fn_nodei( IDENTIFIER_VIRTUAL_P ) +fn_nodei( IDENTIFIER_OPNAME_P ) +fn_nodei( IDENTIFIER_TYPENAME_P ) +fn_nodei( IDENTIFIER_CTOR_OR_DTOR_P ) +fn_nodei( C_TYPE_FIELDS_READONLY ) +/*fn_nodei( C_EXP_ORIGINAL_CODE ) already declared in c-common.h */ +fn_2( C_SET_EXP_ORIGINAL_CODE, int, tree, tree ) +fn_1( ansi_opname, tree, int ) +fn_1( ansi_assopname, tree, int ) +fn_noden( TYPE_IDENTIFIER ) +fn_1( TYPE_NAME_STRING, char*, tree ) +fn_nodei( TYPE_NAME_LENGTH ) +fn_1( TYPE_ASSEMBLER_NAME_STRING, char*, tree ) +fn_nodei( TYPE_ASSEMBLER_NAME_LENGTH ) +fn_noden( TYPE_MAIN_DECL ) +fn_nodei( IS_AGGR_TYPE ) +fn_nodei( CLASS_TYPE_P ) +fn_1( IS_AGGR_TYPE_CODE, int, int ) +fn_2( IS_AGGR_TYPE_2, int, tree, tree ) +fn_nodei( IS_OVERLOAD_TYPE ) +fn_nodei( TYPE_BUILT_IN ) +fn_nodei( TYPE_FOR_JAVA ) +fn_nodei( CP_TYPE_QUALS ) +fn_nodei( CP_TYPE_CONST_P ) +fn_nodei( CP_TYPE_VOLATILE_P ) +fn_nodei( CP_TYPE_RESTRICT_P ) +fn_nodei( CP_TYPE_CONST_NON_VOLATILE_P ) +fn_noden( FNADDR_FROM_VTABLE_ENTRY ) +fn_noden( FUNCTION_ARG_CHAIN ) +fn_noden( FUNCTION_FIRST_USER_PARMTYPE ) +fn_noden( FUNCTION_FIRST_USER_PARM ) +fn_2( PROMOTES_TO_AGGR_TYPE, int, tree, unsigned ) +fn_2( UNIQUELY_DERIVED_FROM_P, int, tree, tree ) +fn_2( ACCESSIBLY_DERIVED_FROM_P, int, tree, tree ) +fn_2( ACCESSIBLY_UNIQUELY_DERIVED_P, int, tree, tree ) +fn_2( PUBLICLY_UNIQUELY_DERIVED_P, int, tree, tree ) +fn_2( DERIVED_FROM_P, int, tree, tree ) +fn_nodei( CLASSTYPE_USE_TEMPLATE ) +fn_noden( CLASSTYPE_INLINE_FRIENDS ) +fn_nodei( TYPE_GETS_DELETE ) +fn_nodei( TYPE_GETS_REG_DELETE ) +fn_nodei( TYPE_VEC_DELETE_TAKES_SIZE ) +fn_nodei( TYPE_VEC_NEW_USES_COOKIE ) +fn_nodei( TYPE_HAS_CONVERSION ) +fn_nodei( TYPE_HAS_ASSIGN_REF ) +fn_nodei( TYPE_HAS_CONST_ASSIGN_REF ) +fn_nodei( TYPE_HAS_INIT_REF ) +fn_nodei( TYPE_HAS_CONST_INIT_REF ) +fn_nodei( TYPE_HAS_NEW_OPERATOR ) +fn_nodei( TYPE_HAS_ARRAY_NEW_OPERATOR ) +fn_nodei( TYPE_BEING_DEFINED ) +fn_nodei( TYPE_REDEFINED ) +fn_noden( CLASSTYPE_RTTI ) +fn_nodei( TYPE_OVERLOADS_CALL_EXPR ) +fn_nodei( TYPE_OVERLOADS_ARRAY_REF ) +fn_nodei( TYPE_OVERLOADS_ARROW ) +fn_nodei( TYPE_USES_MULTIPLE_INHERITANCE ) +fn_nodei( TYPE_USES_VIRTUAL_BASECLASSES ) +fn_noden( CLASSTYPE_METHOD_VEC ) +fn_noden( CLASSTYPE_CONSTRUCTORS ) +fn_noden( CLASSTYPE_DESTRUCTORS ) +fn_2( CLASSTYPE_MARKED_N, int, tree, int ) +fn_nodei( CLASSTYPE_MARKED ) +fn_nodei( CLASSTYPE_MARKED2 ) +fn_nodei( CLASSTYPE_MARKED3 ) +fn_nodei( CLASSTYPE_MARKED4 ) +fn_nodei( CLASSTYPE_MARKED5 ) +fn_nodei( CLASSTYPE_MARKED6 ) +fn_noden( CLASSTYPE_TAGS ) +fn_nodei( CLASSTYPE_HAS_PRIMARY_BASE_P ) +fn_noden( CLASSTYPE_PRIMARY_BINFO ) +fn_nodei( CLASSTYPE_VSIZE ) +fn_noden( CLASSTYPE_VBASECLASSES ) +fn_2( CANONICAL_BINFO, tree, tree, tree ) +fn_nodei( CLASSTYPE_N_BASECLASSES ) +fn_noden( CLASSTYPE_SIZE ) +fn_noden( CLASSTYPE_SIZE_UNIT ) +fn_nodei( CLASSTYPE_ALIGN ) +fn_nodei( CLASSTYPE_USER_ALIGN ) +fn_nodei( CLASSTYPE_ALIGN_UNIT ) +fn_nodei( TYPE_JAVA_INTERFACE ) +fn_noden( CLASSTYPE_PURE_VIRTUALS ) +fn_nodei( CLASSTYPE_GOT_SEMICOLON ) +fn_nodei( CLASSTYPE_NEEDS_VIRTUAL_REINIT ) +fn_nodei( TYPE_HAS_DEFAULT_CONSTRUCTOR ) +fn_nodei( CLASSTYPE_HAS_MUTABLE ) +fn_nodei( TYPE_HAS_MUTABLE_P ) +fn_nodei( CLASSTYPE_NON_POD_P ) +fn_nodei( CLASSTYPE_NEARLY_EMPTY_P ) +fn_nodei( CLASSTYPE_COM_INTERFACE ) +fn_noden( CLASSTYPE_FRIEND_CLASSES ) +fn_noden( CLASSTYPE_BEFRIENDING_CLASSES ) +fn_nodei( CLASSTYPE_DECLARED_CLASS ) +fn_nodei( CLASSTYPE_READONLY_FIELDS_NEED_INIT ) +fn_nodei( CLASSTYPE_REF_FIELDS_NEED_INIT ) +fn_nodei( CLASSTYPE_INTERFACE_ONLY ) +fn_nodei( CLASSTYPE_INTERFACE_KNOWN ) +fn_nodei( CLASSTYPE_INTERFACE_UNKNOWN ) +fn_2( SET_CLASSTYPE_INTERFACE_UNKNOWN_X, int, tree, int ) +fn_nodei( SET_CLASSTYPE_INTERFACE_UNKNOWN ) +fn_nodei( SET_CLASSTYPE_INTERFACE_KNOWN ) +fn_nodei( CLASSTYPE_DEBUG_REQUESTED ) +fn_nodei( BINFO_MARKED ) +fn_nodei( BINFO_VTABLE_PATH_MARKED ) +fn_nodei( BINFO_NEW_VTABLE_MARKED ) +fn_nodei( BINFO_PUSHDECLS_MARKED ) +fn_nodei( BINFO_PRIMARY_P ) +fn_noden( BINFO_SUBVTT_INDEX ) +fn_noden( BINFO_VPTR_INDEX ) +fn_noden( BINFO_PRIMARY_BASE_OF ) +fn_nodei( BINFO_LOST_PRIMARY_P ) +fn_nodei( BINFO_INDIRECT_PRIMARY_P ) +fn_nodei( IDENTIFIER_MARKED ) +fn_noden( CLASSTYPE_VFIELDS ) +fn_noden( VF_BINFO_VALUE ) +fn_noden( VF_BASETYPE_VALUE ) +fn_noden( VF_DERIVED_VALUE ) +fn_noden( BV_DELTA ) +fn_noden( BV_VCALL_INDEX ) +fn_noden( BV_FN ) +fn_nodei( BV_USE_VCALL_INDEX_P ) +fn_nodei( BV_GENERATE_THUNK_WITH_VTABLE_P ) +fn_nodei( TREE_PARMLIST ) +fn_nodei( PARMLIST_ELLIPSIS_P ) +fn_noden( TYPE_RAISES_EXCEPTIONS ) +fn_nodei( TYPE_NOTHROW_P ) +fn_1( NAMESPACE_LEVEL, struct binding_level*, tree ) +fn_nodei( CAN_HAVE_FULL_LANG_DECL_P ) +fn_1( DEFARG_POINTER, const unsigned char *, tree ) +fn_nodei( DECL_NEEDED_P ) +fn_nodei( DECL_IN_MEMORY_P ) +fn_nodei( DECL_LANGUAGE ) +fn_nodei( DECL_CONSTRUCTOR_P ) +fn_nodei( DECL_COMPLETE_CONSTRUCTOR_P ) +fn_nodei( DECL_BASE_CONSTRUCTOR_P ) +fn_nodei( DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P ) +fn_nodei( DECL_COPY_CONSTRUCTOR_P ) +fn_nodei( DECL_DESTRUCTOR_P ) +fn_nodei( DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P ) +fn_nodei( DECL_COMPLETE_DESTRUCTOR_P ) +fn_nodei( DECL_BASE_DESTRUCTOR_P ) +fn_nodei( DECL_DELETING_DESTRUCTOR_P ) +fn_nodei( DECL_CLONED_FUNCTION_P ) +fn_noden( DECL_CLONED_FUNCTION ) +fn_nodei( DECL_DISCRIMINATOR_P ) +fn_nodei( DECL_DISCRIMINATOR ) +fn_nodei( DECL_HAS_VTT_PARM_P ) +fn_nodei( DECL_NEEDS_VTT_PARM_P ) +fn_nodei( DECL_CONV_FN_P ) +fn_2( SET_OVERLOADED_OPERATOR_CODE, enum tree_code, tree, enum tree_code ) +fn_nodei( DECL_OVERLOADED_OPERATOR_P ) +fn_nodei( DECL_ASSIGNMENT_OPERATOR_P ) +fn_nodei( DECL_HAS_IN_CHARGE_PARM_P ) +fn_nodei( DECL_ARRAY_DELETE_OPERATOR_P ) +fn_nodei( DECL_IN_AGGR_P ) +fn_nodei( DECL_INITIALIZED_IN_CLASS_P ) +fn_nodei( DECL_FRIEND_P ) +fn_noden( DECL_BEFRIENDING_CLASSES ) +fn_nodei( DECL_STATIC_FUNCTION_P ) +fn_nodei( DECL_NONSTATIC_MEMBER_FUNCTION_P ) +fn_nodei( DECL_FUNCTION_MEMBER_P ) +fn_nodei( DECL_CONST_MEMFUNC_P ) +fn_nodei( DECL_VOLATILE_MEMFUNC_P ) +fn_nodei( DECL_NONSTATIC_MEMBER_P ) +fn_nodei( DECL_MUTABLE_P ) +fn_nodei( DECL_NONCONVERTING_P ) +fn_nodei( DECL_PURE_VIRTUAL_P ) +fn_nodei( DECL_NEEDS_FINAL_OVERRIDER_P ) +fn_nodei( DECL_THUNK_P ) +fn_nodei( DECL_NON_THUNK_FUNCTION_P ) +fn_nodei( DECL_EXTERN_C_P ) +fn_nodei( DECL_EXTERN_C_FUNCTION_P ) +fn_2 ( SET_DECL_THUNK_P, tree, tree, tree ) +fn_nodei( DECL_PRETTY_FUNCTION_P ) +fn_noden( DECL_CLASS_CONTEXT ) +fn_noden( DECL_FRIEND_CONTEXT ) +fn_2( SET_DECL_FRIEND_CONTEXT, tree, tree, tree ) +fn_noden( CP_DECL_CONTEXT ) +fn_noden( FROB_CONTEXT ) +fn_noden( DECL_VIRTUAL_CONTEXT ) +fn_nodei( DECL_NAMESPACE_SCOPE_P ) +fn_nodei( DECL_CLASS_SCOPE_P ) +fn_nodei( DECL_FUNCTION_SCOPE_P ) +fn_nodei( LOCAL_CLASS_P ) +fn_noden( DECL_NAMESPACE_USING ) +fn_noden( DECL_NAMESPACE_USERS ) +fn_noden( DECL_NAMESPACE_ALIAS ) +fn_noden( ORIGINAL_NAMESPACE ) +fn_nodei( DECL_NAMESPACE_STD_P ) +fn_nodei( DECL_INIT_PRIORITY ) +fn_nodei( TREE_INDIRECT_USING ) +fn_noden( DECL_SHADOWED_FOR_VAR ) +fn_nodei( DECL_PENDING_INLINE_P ) +fn_1( DECL_PENDING_INLINE_INFO, struct unparsed_text *, tree ) +fn_noden( DECL_SORTED_FIELDS ) +fn_nodei( DECL_DEFERRED_FN ) +fn_noden( DECL_TEMPLATE_INFO ) +fn_noden( CLASSTYPE_TEMPLATE_INFO ) +fn_noden( ENUM_TEMPLATE_INFO ) +fn_noden( TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO ) +fn_noden( TYPE_TEMPLATE_INFO ) +fn_2( SET_TYPE_TEMPLATE_INFO, tree, tree, tree ) +fn_noden( TI_TEMPLATE ) +fn_noden( TI_ARGS ) +fn_nodei( TI_PENDING_TEMPLATE_FLAG ) +fn_nodei( TMPL_ARGS_HAVE_MULTIPLE_LEVELS ) +fn_nodei( TMPL_ARGS_DEPTH ) +fn_2( TMPL_ARGS_LEVEL, tree, tree, int ) +fn_3( SET_TMPL_ARGS_LEVEL, tree, tree, int, tree ) +fn_3( TMPL_ARG, tree, tree, int, int ) +fn_4( SET_TMPL_ARG, tree, tree, int, int, tree ) +fn_nodei( NUM_TMPL_ARGS ) +fn_noden( INNERMOST_TEMPLATE_ARGS ) +fn_1( TMPL_PARMS_DEPTH, unsigned HOST_WIDE_INT, tree ) +fn_noden( DECL_TI_TEMPLATE ) +fn_noden( DECL_TI_ARGS ) +fn_noden( CLASSTYPE_TI_TEMPLATE ) +fn_noden( CLASSTYPE_TI_ARGS ) +fn_noden( ENUM_TI_TEMPLATE ) +fn_noden( ENUM_TI_ARGS ) +fn_noden( TYPE_TI_TEMPLATE ) +fn_noden( TYPE_TI_ARGS) +fn_noden( INNERMOST_TEMPLATE_PARMS ) +fn_nodei( TEMPLATE_PARMS_FOR_INLINE ) +fn_1( DECL_SAVED_FUNCTION_DATA, struct cp_language_function *, tree ) +fn_nodei( NEW_EXPR_USE_GLOBAL ) +fn_nodei( DELETE_EXPR_USE_GLOBAL ) +fn_nodei( DELETE_EXPR_USE_VEC ) +fn_nodei( LOOKUP_EXPR_GLOBAL ) +fn_nodei( AGGR_INIT_VIA_CTOR_P ) +fn_nodei( CLASSTYPE_IS_TEMPLATE ) +fn_noden( TYPENAME_TYPE_FULLNAME ) +fn_nodei( IMPLICIT_TYPENAME_P ) +fn_nodei( IMPLICIT_TYPENAME_TYPE_DECL_P ) +fn_nodei( TREE_NEGATED_INT ) +fn_nodei( TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P ) +fn_nodei( TYPE_POLYMORPHIC_P ) +fn_nodei( TYPE_CONTAINS_VPTR_P ) +fn_nodei( DECL_DEAD_FOR_LOCAL ) +fn_nodei( DECL_ERROR_REPORTED ) +fn_nodei( DECL_LOCAL_FUNCTION_P ) +fn_nodei( DECL_ANTICIPATED ) +fn_nodei( C_TYPEDEF_EXPLICITLY_SIGNED ) +fn_nodei( DECL_EXTERNAL_LINKAGE_P ) +fn_1( INTEGRAL_CODE_P, int, int ) +fn_nodei( CP_INTEGRAL_TYPE_P ) +fn_nodei( ARITHMETIC_TYPE_P ) +fn_nodei( TYPE_HAS_CONSTRUCTOR ) +fn_nodei( TREE_HAS_CONSTRUCTOR ) +fn_nodei( EMPTY_CONSTRUCTOR_P ) +fn_nodei( TYPE_HAS_DESTRUCTOR ) +fn_nodei( CLASSTYPE_NON_AGGREGATE ) +fn_nodei( TYPE_NON_AGGREGATE_CLASS ) +fn_nodei( TYPE_HAS_REAL_ASSIGN_REF ) +fn_nodei( TYPE_HAS_COMPLEX_ASSIGN_REF ) +fn_nodei( TYPE_HAS_ABSTRACT_ASSIGN_REF ) +fn_nodei( TYPE_HAS_COMPLEX_INIT_REF ) +fn_nodei( TYPE_HAS_TRIVIAL_DESTRUCTOR1 ) +fn_nodei( TYPE_HAS_NONTRIVIAL_DESTRUCTOR ) +fn_nodei( TYPE_HAS_TRIVIAL_INIT_REF ) +fn_nodei( TYPE_HAS_TRIVIAL_ASSIGN_REF ) +fn_nodei( TYPE_PTRMEM_P ) +fn_nodei( TYPE_PTR_P ) +fn_nodei( TYPE_PTROB_P ) +fn_nodei( TYPE_PTROBV_P ) +fn_nodei( TYPE_PTRFN_P ) +fn_nodei( TYPE_PTRMEMFUNC_P ) +fn_nodei( TYPE_PTRMEMFUNC_FLAG ) +fn_nodei( PTRMEM_OK_P ) +fn_noden( TYPE_PTRMEMFUNC_FN_TYPE ) +fn_noden( TYPE_PTRMEMFUNC_OBJECT_TYPE ) +fn_noden( TYPE_GET_PTRMEMFUNC_TYPE ) +#if 0 /* this one doesn't have a return value */ +fn_2( TYPE_SET_PTRMEMFUNC_TYPE, struct lang_type *, tree, struct lang_type*) +#endif +fn_noden( DELTA2_FROM_PTRMEMFUNC ) +fn_noden( PFN_FROM_PTRMEMFUNC ) +fn_noden( TYPE_PTRMEM_CLASS_TYPE ) +fn_noden( TYPE_PTRMEM_POINTED_TO_TYPE ) +fn_noden( PTRMEM_CST_CLASS ) +fn_noden( PTRMEM_CST_MEMBER ) +fn_nodei( DECL_THIS_EXTERN ) +fn_nodei( DECL_THIS_STATIC ) +fn_nodei( ANON_AGGR_TYPE_P ) +fn_nodei( SET_ANON_AGGR_TYPE_P ) +fn_nodei( ANON_UNION_TYPE_P ) +fn_nodei( TYPE_WAS_ANONYMOUS ) +fn_noden( DECL_FRIENDLIST ) +fn_noden( FRIEND_NAME ) +fn_noden( FRIEND_DECLS ) +fn_noden( DECL_ACCESS ) +fn_nodei( DECL_GLOBAL_CTOR_P ) +fn_nodei( DECL_GLOBAL_DTOR_P ) +fn_nodei( GLOBAL_INIT_PRIORITY ) +fn_noden( DECL_TEMPLATE_PARMS ) +fn_noden( DECL_INNERMOST_TEMPLATE_PARMS ) +fn_nodei( DECL_NTPARMS ) +fn_noden( DECL_TEMPLATE_RESULT ) +fn_noden( DECL_TEMPLATE_INSTANTIATIONS ) +fn_noden( DECL_TEMPLATE_SPECIALIZATIONS ) +fn_nodei( DECL_TEMPLATE_PARM_P ) +fn_nodei( SET_DECL_TEMPLATE_PARM_P ) +fn_nodei( DECL_TEMPLATE_TEMPLATE_PARM_P ) +fn_nodei( DECL_FUNCTION_TEMPLATE_P ) +fn_nodei( DECL_CLASS_TEMPLATE_P ) +fn_nodei( DECL_DECLARES_TYPE_P ) +fn_nodei( DECL_IMPLICIT_TYPEDEF_P ) +fn_nodei( SET_DECL_IMPLICIT_TYPEDEF_P ) +fn_noden( DECL_PRIMARY_TEMPLATE ) +fn_nodei( PRIMARY_TEMPLATE_P ) +fn_nodei( CLASSTYPE_TEMPLATE_LEVEL ) +fn_nodei( DECL_USE_TEMPLATE ) +fn_nodei( DECL_TEMPLATE_INSTANTIATION ) +fn_nodei( CLASSTYPE_TEMPLATE_INSTANTIATION ) +fn_nodei( DECL_TEMPLATE_SPECIALIZATION ) +fn_nodei( SET_DECL_TEMPLATE_SPECIALIZATION ) +fn_nodei( CLASSTYPE_TEMPLATE_SPECIALIZATION ) +fn_nodei( SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ) +fn_nodei( DECL_IMPLICIT_INSTANTIATION ) +fn_nodei( SET_DECL_IMPLICIT_INSTANTIATIO ) +fn_nodei( CLASSTYPE_IMPLICIT_INSTANTIATION ) +fn_nodei( SET_CLASSTYPE_IMPLICIT_INSTANTIATION ) +fn_nodei( DECL_EXPLICIT_INSTANTIATION ) +fn_nodei( SET_DECL_EXPLICIT_INSTANTIATION ) +fn_nodei( CLASSTYPE_EXPLICIT_INSTANTIATION ) +fn_nodei( SET_CLASSTYPE_EXPLICIT_INSTANTIATION ) +fn_nodei( DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION ) +fn_nodei( PARTIAL_INSTANTIATION_P ) +fn_0( PROCESSING_REAL_TEMPLATE_DECL_P, int ) +fn_nodei( DECL_MAYBE_TEMPLATE ) +fn_nodei( DECL_TEMPLATE_INSTANTIATED ) +fn_nodei( DECL_INTERFACE_KNOWN ) +fn_nodei( DECL_DECLARED_INLINE_P ) +fn_nodei( DECL_NOT_REALLY_EXTERN ) +fn_nodei( DECL_REALLY_EXTERN ) +fn_nodei( THUNK_DELTA ) +fn_noden( THUNK_VCALL_OFFSET ) +fn_nodei( THUNK_GENERATE_WITH_VTABLE_P ) +fn_noden( TRY_STMTS ) +fn_noden( TRY_HANDLERS ) +fn_noden( EH_SPEC_STMTS ) +fn_noden( EH_SPEC_RAISES ) +fn_nodei( FN_TRY_BLOCK_P ) +fn_noden( HANDLER_PARMS ) +fn_noden( HANDLER_BODY ) +fn_noden( SUBOBJECT_CLEANUP ) +fn_noden( START_CATCH_TYPE ) +fn_nodei( CTOR_BEGIN_P ) +fn_nodei( CTOR_END_P ) +fn_noden( CALL_DECLARATOR_PARMS ) +fn_noden( CALL_DECLARATOR_QUALS ) +fn_noden( CALL_DECLARATOR_EXCEPTION_SPEC ) +fn_noden( TINST_DECL ) +fn_nodei( TINST_LINE ) +fn_1( TINST_FILE, char*, tree ) +fn_nodei( THIS_NAME_P ) +fn_nodei( VPTR_NAME_P ) +fn_nodei( DESTRUCTOR_NAME_P ) +fn_nodei( VTABLE_NAME_P ) +fn_nodei( VBASE_NAME_P ) +fn_nodei( TEMP_NAME_P ) +fn_nodei( VFIELD_NAME_P ) +fn_nodei( ANON_AGGRNAME_P ) +fn_nodei( ANON_PARMNAME_P ) +fn_2( same_or_base_type_p, int, tree, tree ) +fn_1( TEMPLATE_PARM_INDEX_CAST, template_parm_index*, tree ) +fn_nodei( TEMPLATE_PARM_IDX ) +fn_nodei( TEMPLATE_PARM_LEVEL ) +fn_noden( TEMPLATE_PARM_DESCENDANTS ) +fn_nodei( TEMPLATE_PARM_ORIG_LEVEL ) +fn_noden( TEMPLATE_PARM_DECL ) +fn_noden( TEMPLATE_TYPE_PARM_INDEX ) +fn_nodei( TEMPLATE_TYPE_IDX ) +fn_nodei( TEMPLATE_TYPE_LEVEL ) +fn_nodei( TEMPLATE_TYPE_ORIG_LEVEL ) +fn_noden( TEMPLATE_TYPE_DECL ) +fn_noden( TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL ) +fn_2( cp_build_qualified_type, tree, tree, int ) +fn_3( cp_build_binary_op, tree, enum tree_code, tree, tree ) + +#endif /* ENABLE_IDEBUG */ diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index fb5b2389131..8af09e9c3f4 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -53,6 +53,8 @@ static void cxx_initialize_diagnostics (diagnostic_context *); #define LANG_HOOKS_FINISH cxx_finish #undef LANG_HOOKS_CLEAR_BINDING_STACK #define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything +#undef LANG_HOOKS_FINISH_FILE +#define LANG_HOOKS_FINISH_FILE finish_file #undef LANG_HOOKS_INIT_OPTIONS #define LANG_HOOKS_INIT_OPTIONS c_common_init_options #undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS @@ -189,6 +191,22 @@ static void cxx_initialize_diagnostics (diagnostic_context *); #undef LANG_HOOKS_GIMPLIFY_EXPR #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr +/* APPLE LOCAL begin Objective-C++ */ +/* Redefine the hooks that need to be different for ObjC++. */ +#ifdef OBJCPLUS +static void objcplus_init_options PARAMS ((void)); +#include "objc/objc-act.h" +#undef LANG_HOOKS_NAME +#define LANG_HOOKS_NAME "GNU Objective-C++" +#undef LANG_HOOKS_INIT +#define LANG_HOOKS_INIT objc_init +#undef LANG_HOOKS_FINISH_FILE +#define LANG_HOOKS_FINISH_FILE objc_finish_file +#undef LANG_HOOKS_INIT_OPTIONS +#define LANG_HOOKS_INIT_OPTIONS objcplus_init_options +#endif /* OBJCPLUS */ +/* APPLE LOCAL end Objective-C++ */ + /* Each front end provides its own hooks, for toplev.c. */ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; @@ -202,6 +220,12 @@ const char tree_code_type[] = { #include "c-common.def" 'x', #include "cp-tree.def" +/* APPLE LOCAL begin Objective-C++ */ +#ifdef OBJCPLUS + 'x', +#include "objc-tree.def" +#endif +/* APPLE LOCAL end Objective-C++ */ }; #undef DEFTREECODE @@ -217,6 +241,12 @@ const unsigned char tree_code_length[] = { #include "c-common.def" 0, #include "cp-tree.def" +/* APPLE LOCAL begin Objective-C++ */ +#ifdef OBJCPLUS + 0, +#include "objc-tree.def" +#endif +/* APPLE LOCAL end Objective-C++ */ }; #undef DEFTREECODE @@ -230,6 +260,12 @@ const char *const tree_code_name[] = { #include "c-common.def" "@@dummy", #include "cp-tree.def" +/* APPLE LOCAL begin Objective-C++ */ +#ifdef OBJCPLUS + "@@dummy", +#include "objc-tree.def" +#endif +/* APPLE LOCAL end Objective-C++ */ }; #undef DEFTREECODE @@ -269,6 +305,16 @@ cxx_warn_unused_global_decl (tree decl) return true; } +/* APPLE LOCAL begin Objective-C++ */ +#ifdef OBJCPLUS +static void +objcplus_init_options (void) +{ + flag_objc = 1; + cxx_init_options (); +} +#endif + /* Langhook for expr_size: Tell the backend that the value of an expression of non-POD class type does not include any tail padding; a derived class might have allocated something there. */ @@ -386,3 +432,20 @@ cxx_initialize_diagnostics (diagnostic_context *context) /* It is safe to free this object because it was previously malloc()'d. */ free (base); } + +/* APPLE LOCAL Objective-C++ */ +/* Include the GC roots here instead of in cp/decl.c, so we can + conditionalize on OBJCPLUS. */ +#include "decl.h" +#include "debug.h" +#include "lex.h" +#include "gt-cp-cp-tree-h.h" +#include "gt-cp-decl-h.h" +#ifdef OBJCPLUS +tree objcp_dummy = 0; +#include "gtype-objcp.h" +#else +tree cp_dummy = 0; +#include "gtype-cp.h" +#endif +/* APPLE LOCAL end Objective-C++ */ diff --git a/gcc/cp/cp-root.h b/gcc/cp/cp-root.h new file mode 100644 index 00000000000..3bb87980f0d --- /dev/null +++ b/gcc/cp/cp-root.h @@ -0,0 +1,4 @@ +/* APPLE LOCAL file Objective-C++ */ +/* Empty file to be the base for gtype-cp.h. */ + +extern GTY(()) tree cp_dummy; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f6282105daf..69596bc635c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -223,6 +223,9 @@ struct lang_identifier GTY(()) cxx_binding *bindings; tree class_value; tree class_template_info; + /* APPLE begin LOCAL objc speedup dpatel */ + tree interface_value; + /* APPLE end LOCAL objc speedup dpatel */ tree label_value; tree implicit_decl; tree error_locus; @@ -536,6 +539,8 @@ enum cp_tree_index CPTI_LANG_NAME_C, CPTI_LANG_NAME_CPLUSPLUS, CPTI_LANG_NAME_JAVA, + /* APPLE LOCAL Objective-C++ */ + CPTI_LANG_NAME_OBJC, CPTI_EMPTY_EXCEPT_SPEC, CPTI_NULL, @@ -548,6 +553,12 @@ enum cp_tree_index CPTI_KEYED_CLASSES, + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + CPTI_DELTA2_IDENTIFIER, + CPTI_INDEX_IDENTIFIER, + CPTI_PFN_OR_DELTA2_IDENTIFIER, + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ + CPTI_MAX }; @@ -619,6 +630,12 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; #define deleting_dtor_identifier cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER] #define delta_identifier cp_global_trees[CPTI_DELTA_IDENTIFIER] #define in_charge_identifier cp_global_trees[CPTI_IN_CHARGE_IDENTIFIER] + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ +#define delta2_identifier cp_global_trees[CPTI_DELTA2_IDENTIFIER] +#define index_identifier cp_global_trees[CPTI_INDEX_IDENTIFIER] +#define pfn_or_delta2_identifier cp_global_trees[CPTI_PFN_OR_DELTA2_IDENTIFIER] + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ + /* The name of the parameter that contains a pointer to the VTT to use for this subobject constructor or destructor. */ #define vtt_parm_identifier cp_global_trees[CPTI_VTT_PARM_IDENTIFIER] @@ -631,6 +648,8 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; #define lang_name_c cp_global_trees[CPTI_LANG_NAME_C] #define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS] #define lang_name_java cp_global_trees[CPTI_LANG_NAME_JAVA] +/* APPLE LOCAL Objective-C++ */ +#define lang_name_objc cp_global_trees[CPTI_LANG_NAME_OBJC] /* Exception specifier used for throw(). */ #define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] @@ -879,7 +898,8 @@ enum cplus_tree_code { CTOR_INITIALIZER, TRY_BLOCK, HANDLER, \ EH_SPEC_BLOCK, USING_STMT, TAG_DEFN -enum languages { lang_c, lang_cplusplus, lang_java }; +/* APPLE LOCAL Objective-C++ */ +enum languages { lang_c, lang_cplusplus, lang_java, lang_objc }; /* Macros to make error reporting functions' lives easier. */ #define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE))) @@ -2504,8 +2524,13 @@ struct lang_decl GTY(()) /* Get the POINTER_TYPE to the METHOD_TYPE associated with this pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true, before using this macro. */ -#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) \ - (TREE_TYPE (TYPE_FIELDS (NODE))) + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ \ +#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) \ + *((flag_apple_kext) ? \ + &(TREE_TYPE (TYPE_FIELDS (TREE_TYPE (TREE_CHAIN ( \ + TREE_CHAIN (TYPE_FIELDS (NODE))))))) : \ + &(TREE_TYPE (TYPE_FIELDS (NODE)))) \ + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ /* Returns `A' for a type like `int (A::*)(double)' */ #define TYPE_PTRMEMFUNC_OBJECT_TYPE(NODE) \ @@ -3567,6 +3592,8 @@ extern void note_name_declared_in_class (tree, tree); extern tree get_vtbl_decl_for_binfo (tree); extern tree get_vtt_name (tree); extern tree get_primary_binfo (tree); +/* APPLE LOCAL -findirect-virtual-calls 2001-10-30 sts */ +extern tree build_vfn_ref_using_vtable (tree, tree); extern void debug_class (tree); extern void debug_thunks (tree); @@ -3587,6 +3614,12 @@ extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); /* decl.c */ +/* APPLE LOCAL msg send super */ +extern struct cp_binding_level *get_current_binding_level (void); +/* APPLE LOCAL begin Objective-C++ */ +extern tree grokparms (tree); +extern void store_parm_decls (tree); +/* APPLE LOCAL end Objective-C++ */ extern void insert_block (tree); extern void set_block (tree); extern tree pushdecl (tree); @@ -4265,6 +4298,22 @@ extern tree mangle_ref_init_variable (tree); /* in dump.c */ extern bool cp_dump_tree (void *, tree); +/* APPLE LOCAL begin ddtor double destructor turly 20020215 */ +extern int has_apple_kext_compatibility_attr_p PARAMS ((tree)); +extern int has_empty_operator_delete_p PARAMS ((tree)); +extern int compound_body_is_empty_p PARAMS ((tree)); +/* APPLE LOCAL end ddtor double destructor turly 20020215 */ + +/* APPLE LOCAL begin new tree dump */ +/* in cp-dmp-tree.c */ +extern void cxx_dump_identifier PARAMS ((FILE *, tree, int, int)); +extern void cxx_dump_decl PARAMS ((FILE *, tree, int, int)); +extern void cxx_dump_type PARAMS ((FILE *, tree, int, int)); +extern int cxx_dump_blank_line_p PARAMS ((tree, tree)); +extern int cxx_dump_lineno_p PARAMS ((FILE *, tree)); +extern int cxx_dmp_tree3 PARAMS ((FILE *, tree, int)); +/* APPLE LOCAL end new tree dump */ + /* in cp-simplify.c */ extern int cp_gimplify_expr (tree *, tree *, tree *); extern int cp_gimplify_stmt (tree *, tree *); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8e7eded6047..bffca7900f8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -53,7 +53,9 @@ Boston, MA 02111-1307, USA. */ #include "timevar.h" #include "tree-flow.h" -static tree grokparms (tree); +/* APPLE LOCAL Objective-C++ */ +/* 'grokparms' is now extern, prototype moved to cp-tree.h. */ + static const char *redeclaration_error_message (tree, tree); static int decl_jump_unsafe (tree); @@ -114,7 +116,8 @@ static tree check_special_function_return_type (special_function_kind, tree, tree); static tree push_cp_library_fn (enum tree_code, tree); static tree build_cp_library_fn (tree, enum tree_code, tree); -static void store_parm_decls (tree); +/* APPLE LOCAL Objective-C++ */ +/* 'store_parm_decls' is now extern, prototype moved to cp-tree.h. */ static void initialize_local_var (tree, tree); static void expand_static_init (tree, tree); static tree next_initializable_field (tree); @@ -237,10 +240,17 @@ int function_depth; with __attribute__((deprecated)). An object declared as __attribute__((deprecated)) suppresses warnings of uses of other deprecated items. */ +/* APPLE LOCAL begin unavailable */ +/* An object declared as __attribute__((unavailable)) suppresses + any reports of being declared with unavailable or deprecated + items. */ +/* APPLE LOCAL end unavailable */ enum deprecated_states { DEPRECATED_NORMAL, DEPRECATED_SUPPRESS + /* APPLE LOCAL unavailable */ + , DEPRECATED_UNAVAILABLE_SUPPRESS }; static enum deprecated_states deprecated_state = DEPRECATED_NORMAL; @@ -1297,6 +1307,9 @@ duplicate_decls (tree newdecl, tree olddecl) olddecl = TREE_VALUE (olddecl); cp_error_at ("previous declaration of `%#D'", olddecl); + /* New decl is completely inconsistent with the old one => + tell caller to replace the old one. */ + return error_mark_node; } else if (!types_match) @@ -1828,6 +1841,8 @@ duplicate_decls (tree newdecl, tree olddecl) regardless of declaration matches. */ SET_DECL_RTL (newdecl, DECL_RTL (olddecl)); } + else + DECL_ESTIMATED_INSNS (newdecl) = DECL_ESTIMATED_INSNS (olddecl); DECL_RESULT (newdecl) = DECL_RESULT (olddecl); /* Don't clear out the arguments if we're redefining a function. */ @@ -2859,6 +2874,8 @@ initialize_predefined_identifiers (void) static const predefined_identifier predefined_identifiers[] = { { "C++", &lang_name_cplusplus, 0 }, { "C", &lang_name_c, 0 }, + /* APPLE LOCAL Objective-C++ */ + { "Objective-C", &lang_name_objc, 0 }, /* this is DEPRECATED */ { "Java", &lang_name_java, 0 }, { CTOR_NAME, &ctor_identifier, 1 }, { "__base_ctor", &base_ctor_identifier, 1 }, @@ -2885,6 +2902,45 @@ initialize_predefined_identifiers (void) if (pid->ctor_or_dtor_p) IDENTIFIER_CTOR_OR_DTOR_P (*pid->node) = 1; } + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + if (flag_apple_kext) + { + /* This is snarfed from the 2.95 cp-tree.h. The mechanism is + completely different from gcc3 (see cp-tree.h, and read the + comment just above 'enum ptrmemfunc_vbit_where_t'. Sigh. + + A 2.95 pointer-to-function member type looks like: + + struct { + short __delta; + short __index; + union { + P __pfn; + short __delta2; + } __pfn_or_delta2; + }; + + where P is a POINTER_TYPE to a METHOD_TYPE appropriate for the + pointer to member. The fields are used as follows: + + If __INDEX is -1, then the function to call is non-virtual, and + is located at the address given by __PFN. + + If __INDEX is zero, then this a NULL pointer-to-member. + + Otherwise, the function to call is virtual. Then, __DELTA2 gives + the offset from an instance of the object to the virtual function + table, and __INDEX - 1 is the index into the vtable to use to + find the function. + + The value to use for the THIS parameter is the address of the + object plus __DELTA. */ + + delta2_identifier = get_identifier ("__delta2"); + index_identifier = get_identifier ("__index"); + pfn_or_delta2_identifier = get_identifier ("__pfn_or_delta2"); + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ } /* Create the predefined scalar types of C, @@ -2974,6 +3030,11 @@ cxx_init_decl_processing (void) record_builtin_type (RID_MAX, NULL, string_type_node); #endif + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + if (flag_apple_kext) + delta_type_node = short_integer_type_node; + else + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ delta_type_node = ptrdiff_type_node; vtable_index_type = ptrdiff_type_node; @@ -3231,7 +3292,10 @@ builtin_function (const char* name, { /* All builtins that don't begin with an '_' should additionally go in the 'std' namespace. */ - if (name[0] != '_') + /* APPLE LOCAL begin alloca not in std */ + /* Don't use `std' namespace for alloca. */ + if (name[0] != '_' && strcmp (name, "alloca")) + /* APPLE LOCAL end alloca not in std */ { push_namespace (std_identifier); builtin_function_1 (name, type, std_node, code, class, libname, attrs); @@ -3344,6 +3408,7 @@ push_throw_library_fn (tree name, tree type) TREE_NOTHROW (fn) = 0; return fn; } + /* When we call finish_struct for an anonymous union, we create default copy constructors and such. But, an anonymous union @@ -3623,6 +3688,8 @@ start_decl (tree declarator, tree decl; tree type, tem; tree context; + /* APPLE LOCAL unavailable */ + tree a; /* This should only be done once on the top most decl. */ if (have_extern_spec) @@ -3632,10 +3699,34 @@ start_decl (tree declarator, have_extern_spec = false; } - /* An object declared as __attribute__((deprecated)) suppresses - warnings of uses of other deprecated items. */ + /* APPLE LOCAL begin unavailable */ + /* An object declared as __attribute__((unavailable)) suppresses + any reports of being declared with unavailable or deprecated + items. An object declared as __attribute__((deprecated)) + suppresses warnings of uses of other deprecated items. */ +#ifdef A_LESS_INEFFICENT_WAY /* which I really don't want to do! */ if (lookup_attribute ("deprecated", attributes)) deprecated_state = DEPRECATED_SUPPRESS; + else if (lookup_attribute ("unavailable", attributes)) + deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS; +#else /* a more efficient way doing what lookup_attribute would do */ + for (a = attributes; a; a = TREE_CHAIN (a)) + { + tree name = TREE_PURPOSE (a); + if (TREE_CODE (name) == IDENTIFIER_NODE) + if (is_attribute_p ("deprecated", name)) + { + deprecated_state = DEPRECATED_SUPPRESS; + break; + } + if (is_attribute_p ("unavailable", name)) + { + deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS; + break; + } + } +#endif + /* APPLE LOCAL end unavailable */ attributes = chainon (attributes, prefix_attributes); @@ -4070,6 +4161,14 @@ maybe_commonize_var (tree decl) } else { + /* APPLE LOCAL begin coalescing */ +#ifdef MAKE_DECL_COALESCED + if (DECL_INTERFACE_KNOWN (current_function_decl)) + DECL_EXTERNAL (decl) = DECL_EXTERNAL (current_function_decl); + TREE_PUBLIC (decl) = 1; + MAKE_DECL_COALESCED (decl); +#else + /* APPLE LOCAL end coalescing */ if (DECL_INITIAL (decl) == NULL_TREE || DECL_INITIAL (decl) == error_mark_node) { @@ -4089,6 +4188,8 @@ maybe_commonize_var (tree decl) warning ("%J you can work around this by removing the initializer", decl); } +/* APPLE LOCAL coalescing */ +#endif } } else if (DECL_LANG_SPECIFIC (decl) && DECL_COMDAT (decl)) @@ -4587,6 +4688,17 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) isn't stored in the tree, yet) */ if (defer_p && asmspec) make_decl_rtl (decl, asmspec); + /* APPLE LOCAL begin static const members turly 20020110 */ + /* Static const members which require runtime initialisation should + not be placed in readonly memory. Avoid this by temporarily + whacking the TREE_READONLY bit. */ + else if (!defer_p && init != NULL_TREE && TREE_READONLY (decl) && toplev) + { + TREE_READONLY (decl) = 0; + rest_of_decl_compilation (decl, asmspec, toplev, at_eof); + TREE_READONLY (decl) = 1; + } + /* APPLE LOCAL end static const members turly 20020110 */ /* If we're not deferring, go ahead and assemble the variable. */ else if (!defer_p) rest_of_decl_compilation (decl, asmspec, toplev, at_eof); @@ -5905,12 +6017,48 @@ build_ptrmemfunc_type (tree type) unqualified_variant = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type)); + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + if (flag_apple_kext) + { + abort (); +#if 0 + /* MERGE FIXME */ + tree u = make_aggr_type (UNION_TYPE); + SET_IS_AGGR_TYPE (u, 0); + fields = build_decl (FIELD_DECL, pfn_identifier, type); + TREE_CHAIN (fields) + = build_decl (FIELD_DECL, delta2_identifier, delta_type_node); + finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node); + TYPE_NAME (u) = NULL_TREE; + + t = make_aggr_type (RECORD_TYPE); + + /* Let the front-end know this is a pointer to member function... */ + TYPE_PTRMEMFUNC_FLAG (t) = 1; + /* ... and not really an aggregate. */ + SET_IS_AGGR_TYPE (t, 0); + + fields = build_decl (FIELD_DECL, delta_identifier, delta_type_node); + TREE_CHAIN (fields) = + build_decl (FIELD_DECL, index_identifier, delta_type_node); + TREE_CHAIN (TREE_CHAIN (fields)) = + build_decl (FIELD_DECL, pfn_or_delta2_identifier, u); + finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node); +#endif + } + else + { + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ + t = make_aggr_type (RECORD_TYPE); /* Let the front-end know this is a pointer to member function... */ TYPE_PTRMEMFUNC_FLAG (t) = 1; /* ... and not really an aggregate. */ SET_IS_AGGR_TYPE (t, 0); + /* APPLE LOCAL 2.95-ptmf-compatibility turly 20020313 */ + } + field = build_decl (FIELD_DECL, pfn_identifier, type); fields = field; @@ -6707,11 +6855,38 @@ grokdeclarator (tree declarator, /* If the entire declaration is itself tagged as deprecated then suppress reports of deprecated items. */ + /* APPLE LOCAL begin unavailable */ + /* If the entire declaration is itself tagged as unavailable then + suppress reports of unavailable/deprecated items. If the + entire declaration is tagged as only deprecated we still + report unavailable uses. */ if (!adding_implicit_members && id && TREE_DEPRECATED (id)) { - if (deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (id); + if (TREE_UNAVAILABLE (id)) + { + if (deprecated_state != DEPRECATED_UNAVAILABLE_SUPPRESS) + warn_deprecated_use (id); + #if 0 + returned_attrs + = chainon (returned_attrs, + build_tree_list (get_identifier ("unavailable"), + NULL_TREE)); + #endif + } + else + { + if (deprecated_state != DEPRECATED_SUPPRESS + && deprecated_state != DEPRECATED_UNAVAILABLE_SUPPRESS) + warn_deprecated_use (id); + #if 0 + returned_attrs + = chainon (returned_attrs, + build_tree_list (get_identifier ("deprecated"), + NULL_TREE)); + #endif + } } + /* APPLE LOCAL end unavailable */ if (TREE_CODE (id) == IDENTIFIER_NODE) { @@ -6880,6 +7055,8 @@ grokdeclarator (tree declarator, RIDBIT_RESET (RID_LONG, specbits); type = build_qualified_type (long_double_type_node, cp_type_quals (type)); + /* APPLE LOCAL -Wlong-double dpatel */ + warn_about_long_double (); } /* Check all other uses of type modifiers. */ @@ -8580,7 +8757,8 @@ check_default_argument (tree decl, tree arg) Also set last_function_parms to the chain of PARM_DECLs. */ -static tree +/* APPLE LOCAL Objective-C++ */ +tree grokparms (tree first_parm) { tree result = NULL_TREE; @@ -9684,8 +9862,9 @@ start_enum (tree name) /* If this is the real definition for a previous forward reference, fill in the contents in the same object that used to be the forward reference. */ - - if (name != NULL_TREE) + /* APPLE LOCAL do not forward reference anonymous enum */ + /* Note that an anonymous enum cannot be forward-referenced. */ + if (name != NULL_TREE && !ANON_AGGRNAME_P (name)) enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1); if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE) @@ -10242,6 +10421,9 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) /* Start the statement-tree, start the tree now. */ begin_stmt_tree (&DECL_SAVED_TREE (decl1)); + /* Don't double-count statements in templates. */ + DECL_ESTIMATED_INSNS (decl1) = 0; + /* Let the user know we're compiling this function. */ announce_function (decl1); @@ -10388,6 +10570,9 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) begin_scope (sk_function_parms, decl1); + /* APPLE LOCAL weak_import (Radar 2809704) ilr */ + cplus_decl_attributes (&decl1, attrs, (int)ATTR_FLAG_FUNCTION_DEF); + ++function_depth; if (DECL_DESTRUCTOR_P (decl1)) @@ -10409,7 +10594,8 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) Also install to binding contour return value identifier, if any. */ -static void +/* APPLE LOCAL Objective-C++ */ +/* static */ void /* 'store_parm_decls' is extern for Obj-C++ */ store_parm_decls (tree current_function_parms) { tree fndecl = current_function_decl; @@ -11099,6 +11285,26 @@ cxx_maybe_build_cleanup (tree decl) { int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; tree rval; + /* APPLE LOCAL begin double destructor turly 20020214 */ + special_function_kind dtor = sfk_complete_destructor; + if (flag_apple_kext + && has_apple_kext_compatibility_attr_p (type)) + { + /* If we have a trivial operator delete (), we can go ahead and + just use the deleting destructor, sfk_deleting_destructor. */ + + if (! has_empty_operator_delete_p (type) || pedantic) + { + cp_warning_at ("'%D' is an instance of a class which does " + "not allow global or stack-based objects; it " + "does not have an empty `operator delete', and " + "so it will ** NOT ** be destructed.", decl); + return 0; + } + dtor = sfk_deleting_destructor; + } + /* APPLE LOCAL end double destructor turly 20020214 */ + if (TREE_CODE (type) == ARRAY_TYPE) rval = decl; @@ -11114,7 +11320,8 @@ cxx_maybe_build_cleanup (tree decl) flags |= LOOKUP_NONVIRTUAL; rval = build_delete (TREE_TYPE (rval), rval, - sfk_complete_destructor, flags, 0); + /* APPLE LOCAL double destructor */ + dtor, flags, 0); if (TYPE_USES_VIRTUAL_BASECLASSES (type) && ! TYPE_HAS_DESTRUCTOR (type)) @@ -11244,4 +11451,5 @@ cp_missing_noreturn_ok_p (tree decl) } #include "gt-cp-decl.h" -#include "gtype-cp.h" +/* APPLE LOCAL Objective-C++ */ +/* Move gtype-cp.h to cp-lang.c. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a802fd4bab1..b783ea990c6 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -968,6 +968,8 @@ grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree, cp_finish_decl (value, init, NULL_TREE, flags); DECL_INITIAL (value) = init; DECL_IN_AGGR_P (value) = 1; + /* APPLE LOCAL Objective-C++ */ + objc_check_decl (value); return value; } if (TREE_CODE (value) == FUNCTION_DECL) @@ -1049,6 +1051,10 @@ grokbitfield (tree declarator, tree declspecs, tree width) } DECL_IN_AGGR_P (value) = 1; + + /* APPLE LOCAL Objective-C++ */ + objc_check_decl (value); + return value; } @@ -1555,6 +1561,9 @@ maybe_emit_vtables (tree ctype) { tree vtbl; tree primary_vtbl; + /* APPLE LOCAL begin coalescing radar 2997605 */ + int coalesce_vtables; + /* APPLE LOCAL end coalescing radar 2997605 */ bool needed = false; /* If the vtables for this class have already been emitted there is @@ -1586,6 +1595,22 @@ maybe_emit_vtables (tree ctype) else if (TREE_PUBLIC (vtbl) && !DECL_COMDAT (vtbl)) needed = true; + /* APPLE LOCAL begin coalescing radar 2997605 */ + /* Check if we're going to coalesce these vtables. On other systems + vtables are always weak. We can't do that on OS X because + coalescing implies private extern, and making all vtables private + extern would break code that defines classes in dylibs. So + instead we'll only coalesce vtables that would get emitted in + multiple translation units: implicit class template + instantiations, classes with no key methods, and classes whose + key methods weren't inline in the class definition but turned out + to be inline later. */ + if (CLASSTYPE_USE_TEMPLATE (ctype)) + coalesce_vtables = CLASSTYPE_IMPLICIT_INSTANTIATION (ctype); + else + coalesce_vtables = !CLASSTYPE_KEY_METHOD (ctype) + || DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (ctype)); + /* APPLE LOCAL end coalescing radar 2997605 */ /* The ABI requires that we emit all of the vtables if we emit any of them. */ @@ -1636,6 +1661,13 @@ maybe_emit_vtables (tree ctype) if (flag_weak) comdat_linkage (vtbl); + /* APPLE LOCAL begin coalescing radar 2997605 */ +#ifdef MAKE_DECL_COALESCED + if (coalesce_vtables) + MAKE_DECL_COALESCED (vtbl); +#endif /* MAKE_DECL_COALESCED */ + /* APPLE LOCAL end coalescing radar 2997605 */ + rest_of_decl_compilation (vtbl, NULL, 1, 1); /* Because we're only doing syntax-checking, we'll never end up @@ -1710,9 +1742,25 @@ import_export_decl (tree decl) } else comdat_linkage (decl); + /* APPLE LOCAL begin coalescing */ + /* coalesce inline member functions */ +#ifdef MAKE_DECL_COALESCED + if (DECL_DECLARED_INLINE_P (decl)) + { + MAKE_DECL_COALESCED (decl); + } +#endif /* MAKE_DECL_COALESCED */ + /* APPLE LOCAL end coalescing */ } + /* APPLE LOCAL begin coalesce inline functions */ else - comdat_linkage (decl); + { + comdat_linkage (decl); +#ifdef MAKE_DECL_COALESCED + MAKE_DECL_COALESCED(decl); +#endif /* MAKE_DECL_COALESCED */ + } + /* APPLE LOCAL end coalesce inline functions */ DECL_INTERFACE_KNOWN (decl) = 1; } @@ -1735,7 +1783,9 @@ import_export_tinfo (tree decl, tree type, bool is_in_library) /* If -fno-rtti, we're not necessarily emitting this stuff with the class, so go ahead and emit it now. This can happen when a class is used in exception handling. */ - && flag_rtti) + && flag_rtti + /* APPLE LOCAL Jaguar C++ abi compat mrs */ + && abi_version_at_least (1)) { DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type); DECL_COMDAT (decl) = 0; @@ -1744,6 +1794,12 @@ import_export_tinfo (tree decl, tree type, bool is_in_library) { DECL_NOT_REALLY_EXTERN (decl) = 1; DECL_COMDAT (decl) = 1; + /* APPLE LOCAL coalescing */ +#ifdef MAKE_DECL_COALESCED + TREE_PUBLIC (decl) = 1; + if (! is_in_library) + MAKE_DECL_COALESCED (decl); +#endif /* MAKE_DECL_COALESCED */ } /* Now override some cases. */ @@ -1814,6 +1870,11 @@ get_guard (tree decl) if (TREE_PUBLIC (decl)) DECL_WEAK (guard) = DECL_WEAK (decl); + /* APPLE LOCAL coalescing */ +#ifdef MAKE_DECL_COALESCED + if (TREE_PUBLIC (decl) || DECL_COALESCED (decl)) + MAKE_DECL_COALESCED (guard); +#endif DECL_ARTIFICIAL (guard) = 1; TREE_USED (guard) = 1; pushdecl_top_level_and_finish (guard, NULL_TREE); @@ -1920,6 +1981,14 @@ start_objects (int method_type, int initp) DECL_GLOBAL_DTOR_P (current_function_decl) = 1; DECL_LANG_SPECIFIC (current_function_decl)->decl_flags.u2sel = 1; + /* APPLE LOCAL begin static structors in __StaticInit section */ +#ifdef STATIC_INIT_SECTION + if ( ! flag_apple_kext) + DECL_SECTION_NAME (current_function_decl) = + build_string (strlen (STATIC_INIT_SECTION), STATIC_INIT_SECTION); +#endif + /* APPLE LOCAL end static structors in __StaticInit section */ + body = begin_compound_stmt (/*has_no_scope=*/false); /* We cannot allow these functions to be elided, even if they do not @@ -2026,6 +2095,14 @@ start_static_storage_duration_function (unsigned count) TREE_PUBLIC (ssdf_decl) = 0; DECL_ARTIFICIAL (ssdf_decl) = 1; + /* APPLE LOCAL begin static structors in __StaticInit section */ +#ifdef STATIC_INIT_SECTION + if ( ! flag_apple_kext) + DECL_SECTION_NAME (ssdf_decl) = build_string (strlen (STATIC_INIT_SECTION), + STATIC_INIT_SECTION); +#endif + /* APPLE LOCAL end static structors in __StaticInit section */ + /* Put this function in the list of functions to be called from the static constructors and destructors. */ if (!ssdf_decls) @@ -2538,6 +2615,11 @@ finish_file (void) if (pch_file) c_common_write_pch (); + /* APPLE LOCAL Symbol Separation */ + /* Write context information. */ + if (dbg_dir) + c_common_write_context (); + /* Otherwise, GDB can get confused, because in only knows about source for LINENO-1 lines. */ input_line -= 1; @@ -2783,6 +2865,22 @@ finish_file (void) import_export_decl (decl); if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl)) DECL_EXTERNAL (decl) = 0; + /* APPLE LOCAL begin write used class statics turly 20020226 */ +#ifdef MACHOPIC_VAR_REFERRED_TO_P + else + if (TREE_USED (decl) && DECL_INITIAL (decl) != 0 + && DECL_INITIAL (decl) != error_mark_node + && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR + && DECL_EXTERNAL (decl) + && MACHOPIC_VAR_REFERRED_TO_P (IDENTIFIER_POINTER ( + DECL_ASSEMBLER_NAME (decl)))) + { + /* Force a local copy of this decl to be written. */ + DECL_EXTERNAL (decl) = 0; + TREE_PUBLIC (decl) = 0; + } +#endif + /* APPLE LOCAL end write used class statics turly 20020226 */ } if (pending_statics && wrapup_global_declarations (&VARRAY_TREE (pending_statics, 0), diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c index e6c9ee6892a..a73db2a4352 100644 --- a/gcc/cp/g++spec.c +++ b/gcc/cp/g++spec.c @@ -46,6 +46,10 @@ Boston, MA 02111-1307, USA. */ #define LIBSTDCXX_PROFILE "-lstdc++" #endif +/* APPLE LOCAL begin radar 3554191 */ +extern unsigned int macosx_version_min_required; /* defined in gcc.c */ +/* APPLE LOCAL end radar 3554191 */ + void lang_specific_driver (int *in_argc, const char *const **in_argv, int *in_added_libraries) @@ -241,6 +245,13 @@ lang_specific_driver (int *in_argc, const char *const **in_argv, shared_libgcc = 0; #endif + /* APPLE LOCAL begin radar 3554191 */ + { + if (macosx_version_min_required && macosx_version_min_required < 1040) + shared_libgcc = 0; + } + /* APPLE LOCAL end radar 3554191 */ + /* Make sure to have room for the trailing NULL argument. */ num_args = argc + added + need_math + shared_libgcc + (library > 0) + 1; arglist = xmalloc (num_args * sizeof (char *)); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 04e70bcc89d..f246a613eac 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2978,6 +2978,16 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type), /*global_p=*/false, NULL_TREE); } + /* APPLE LOCAL begin double destructor matt 20020501 */ + /* If we're compiling a class in kext compatibility mode we + don't have a non-deleting destructor, so we unconditionally + generate a reference to the deleting variety. */ + if (flag_apple_kext && has_apple_kext_compatibility_attr_p (type)) + { + my_friendly_assert (auto_delete != sfk_base_destructor, 20020501); + auto_delete = sfk_deleting_destructor; + } + /* APPLE LOCAL end double destructor matt 20020501 */ expr = build_dtor_call (build_indirect_ref (addr, NULL), auto_delete, flags); diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h index 5815ea57896..732ac2ed0c9 100644 --- a/gcc/cp/lang-specs.h +++ b/gcc/cp/lang-specs.h @@ -43,10 +43,13 @@ Boston, MA 02111-1307, USA. */ cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\ %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\ %(cc1_options) %2 %{+e1*}\ - -o %g.s %{!o*:--output-pch=%i.gch} %W{o*:--output-pch=%*}%V}}}", + "/* APPLE LOCAL symbol separation */" \ + %(dbg_ss) %(pch)}}}", CPLUSPLUS_CPP_SPEC}, {"@c++", "%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\ + "/* APPLE LOCAL prohibit -arch with -E and -S */"\ + %{E|S:%{@:%e-E and -S are not allowed with multiple -arch flags}}\ %{!E:%{!M:%{!MM:\ %{save-temps|no-integrated-cpp:cc1plus -E\ %(cpp_options) %2 -o %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 2239c76ca87..4fa16394ba5 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -239,6 +239,8 @@ struct resword _true_. */ #define D_EXT 0x01 /* GCC extension */ #define D_ASM 0x02 /* in C99, but has a switch to turn it off */ +/* APPLE LOCAL Objective-C++ */ +#define D_OBJC 0x10 /* Objective C only */ CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT); @@ -266,6 +268,8 @@ static const struct resword reswords[] = { "__inline__", RID_INLINE, 0 }, { "__label__", RID_LABEL, 0 }, { "__null", RID_NULL, 0 }, + /* APPLE LOCAL private extern */ + { "__private_extern__", RID_PRIVATE_EXTERN, 0 }, { "__offsetof", RID_OFFSETOF, 0 }, { "__offsetof__", RID_OFFSETOF, 0 }, { "__real", RID_REALPART, 0 }, @@ -343,7 +347,33 @@ static const struct resword reswords[] = { "volatile", RID_VOLATILE, 0 }, { "wchar_t", RID_WCHAR, 0 }, { "while", RID_WHILE, 0 }, - + /* APPLE LOCAL begin Objective-C++ */ + { "id", RID_ID, D_OBJC }, + + /* These objc keywords are recognized only immediately after + an '@'. Note that some of these overlap with existing C++ keywords. */ +/*{ "class", RID_AT_CLASS, D_OBJC }, OVERLAP */ + { "compatibility_alias", RID_AT_ALIAS, D_OBJC }, + { "defs", RID_AT_DEFS, D_OBJC }, + { "encode", RID_AT_ENCODE, D_OBJC }, + { "end", RID_AT_END, D_OBJC }, + { "implementation", RID_AT_IMPLEMENTATION, D_OBJC }, + { "interface", RID_AT_INTERFACE, D_OBJC }, +/*{ "private", RID_AT_PRIVATE, D_OBJC }, OVERLAP */ +/*{ "protected", RID_AT_PROTECTED, D_OBJC }, OVERLAP */ + { "protocol", RID_AT_PROTOCOL, D_OBJC }, +/*{ "public", RID_AT_PUBLIC, D_OBJC }, OVERLAP */ + { "selector", RID_AT_SELECTOR, D_OBJC }, + + /* These are recognized only in protocol-qualifier context + (see above) */ + { "bycopy", RID_BYCOPY, D_OBJC }, + { "byref", RID_BYREF, D_OBJC }, + { "in", RID_IN, D_OBJC }, + { "inout", RID_INOUT, D_OBJC }, + { "oneway", RID_ONEWAY, D_OBJC }, + { "out", RID_OUT, D_OBJC }, + /* APPLE LOCAL end Objective-C++ */ }; void @@ -354,6 +384,9 @@ init_reswords (void) int mask = ((flag_no_asm ? D_ASM : 0) | (flag_no_gnu_keywords ? D_EXT : 0)); + /* APPLE LOCAL objc++ */ + mask |= D_OBJC; + ridpointers = ggc_calloc ((int) RID_MAX, sizeof (tree)); for (i = 0; i < ARRAY_SIZE (reswords); i++) { @@ -363,6 +396,25 @@ init_reswords (void) if (! (reswords[i].disable & mask)) C_IS_RESERVED_WORD (id) = 1; } + + /* APPLE LOCAL begin private extern Radar 2872481 ilr */ + /* For C++ there is always a -D__private_extern__=extern on the + command line. However, if -fpreprocessed was specified then + macros are not expanded so the -D is meaningless. But this + replacement is required for C++. There for we have to "pretend" + that '__private_extern__' is 'extern' and we can do this simply by + making the rid code for '__private_extern__' be the same as for + extern. Note, we probably could always do this here since + '__private_extern__' is always to be treated like 'extern' for + c++. But we'll be conservative and only do it when -fpreprocessed + is specified and depend on the macro substitution in all other + cases. */ + if (flag_preprocessed) + { + id = get_identifier ("__private_extern__"); + C_RID_CODE (id) = RID_EXTERN; + } + /* APPLE LOCAL end private extern Radar 2872481 ilr */ } static void @@ -427,6 +479,14 @@ cxx_init (void) init_repo (main_input_filename); pop_srcloc(); + + /* APPLE LOCAL gdb only used symbols */ +#ifdef DBX_ONLY_USED_SYMBOLS + /* By default we want to use -gused for C++ and Objective-C++. */ + if (flag_debug_only_used_symbols == -1) + flag_debug_only_used_symbols = 1; +#endif + return true; } diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h index 35c3503ea41..0a9c88478d1 100644 --- a/gcc/cp/lex.h +++ b/gcc/cp/lex.h @@ -65,4 +65,19 @@ typedef unsigned long RID_BIT_TYPE; /* assumed at least 32 bits */ #define RIDBIT_RESET_ALL(V) do { (V) = 0; } while (0) #endif +/* APPLE LOCAL begin Objective-C++ */ +/* Parser/lexer state pertinent to ObjC++. */ +extern int objc_receiver_context; +extern int objc_declarator_context; +extern int objc_msg_context; +extern int objc_public_flag; +extern int objc_need_raw_identifier; +extern int objc_pq_context; + +#define OBJC_NEED_RAW_IDENTIFIER(VAL) \ + do { if (flag_objc) objc_need_raw_identifier = VAL; } \ + while (0) + +/* APPLE LOCAL end Objective-C++ */ + #endif /* ! GCC_CP_LEX_H */ diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 2580d39866f..577159c4753 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -59,6 +59,7 @@ #include "toplev.h" #include "varray.h" #include "flags.h" +#include "target.h" /* Debugging support. */ @@ -1306,10 +1307,8 @@ write_identifier (const char *identifier) ::= C3 # complete object allocating constructor Currently, allocating constructors are never used. - - We also need to provide mangled names for the maybe-in-charge - constructor, so we treat it here too. mangle_decl_string will - append *INTERNAL* to that, to make sure we never emit it. */ + APPLE LOCAL decloning +*/ static void write_special_name_constructor (const tree ctor) @@ -1322,6 +1321,11 @@ write_special_name_constructor (const tree ctor) write_string ("C1"); else if (DECL_BASE_CONSTRUCTOR_P (ctor)) write_string ("C2"); + /* APPLE LOCAL begin decloning */ + /* This is the old-style "[unified]" constructor. */ + else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (ctor)) + write_string ("C4"); + /* APPLE LOCAL end decloning */ else abort (); } @@ -1350,6 +1354,11 @@ write_special_name_destructor (const tree dtor) write_string ("D1"); else if (DECL_BASE_DESTRUCTOR_P (dtor)) write_string ("D2"); + /* APPLE LOCAL begin decloning */ + else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (dtor)) + /* This is the old-style "[unified]" destructor. */ + write_string ("D4"); + /* APPLE LOCAL end decloning */ else abort (); } @@ -1501,12 +1510,24 @@ write_type (tree type) case BOOLEAN_TYPE: case INTEGER_TYPE: /* Includes wchar_t. */ case REAL_TYPE: + { + /* Handle any target-specific fundamental types. */ + const char *target_mangling + = targetm.mangle_fundamental_type (type); + + if (target_mangling) + { + write_string (target_mangling); + return; + } + /* If this is a typedef, TYPE may not be one of the standard builtin type nodes, but an alias of one. Use TYPE_MAIN_VARIANT to get to the underlying builtin type. */ write_builtin_type (TYPE_MAIN_VARIANT (type)); ++is_builtin_type; break; + } case COMPLEX_TYPE: write_char ('C'); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index bb34d822157..1d61c165546 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -397,6 +397,14 @@ use_thunk (tree thunk_fndecl, bool emit_p) return; } + /* APPLE LOCAL begin coalescing */ + /* coalesce thunks */ +#if defined(COALESCE_STATIC_THUNK) + if (DECL_VISIBILITY (function) == VISIBILITY_HIDDEN || !TREE_PUBLIC (function) || DECL_INLINE (function)) + COALESCE_STATIC_THUNK (thunk_fndecl, /* public*/ 0); +#endif /* COALESCE_STATIC_THUNK */ + /* APPLE LOCAL end coalescing */ + push_to_top_level (); #ifdef ASM_OUTPUT_DEF diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 1be4d8afdcc..f36b0ea519c 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -46,6 +46,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA static tree calls_setjmp_r (tree *, int *, void *); static void update_cloned_parm (tree, tree); +/* APPLE LOCAL begin structor thunks */ +static int maybe_alias_body (tree fn, tree clone); +static int maybe_thunk_body (tree fn); +/* APPLE LOCAL end structor thunks */ /* Called from calls_setjmp_p via walk_tree. */ @@ -96,6 +100,165 @@ update_cloned_parm (tree parm, tree cloned_parm) DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm); } +/* APPLE LOCAL begin structor thunks */ +/* FN is a constructor or destructor, and there are FUNCTION_DECLs cloned from it nearby. + If the clone and the original funciton have identical parameter lists, + it is a fully-degenerate (does absolutely nothing) thunk. + Make the clone an alias for the original function label. */ +static int +maybe_alias_body (tree fn ATTRIBUTE_UNUSED, tree clone ATTRIBUTE_UNUSED) +{ + extern FILE *asm_out_file ATTRIBUTE_UNUSED; + +#ifdef ASM_MAYBE_ALIAS_BODY + ASM_MAYBE_ALIAS_BODY (asm_out_file, fn, clone); +#endif + return 0; +} + +/* FN is a constructor or destructor, and there are FUNCTION_DECLs + cloned from it nearby. Instead of cloning this body, leave it + alone and create tiny one-call bodies for the cloned + FUNCTION_DECLs. These clones are sibcall candidates, and their + resulting code will be very thunk-esque. */ +static int +maybe_thunk_body (tree fn) +{ + tree call, clone, expr_stmt, fn_parm, fn_parm_typelist, last_arg, start; + int parmno, vtt_parmno; + + if (flag_apple_kext || flag_clone_structors) + return 0; + + /* If we've already seen this structor, avoid re-processing it. */ + if (TREE_ASM_WRITTEN (fn)) + return 1; + + /* If function accepts variable arguments, give up. */ + last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn))); + if ( ! VOID_TYPE_P (TREE_VALUE (last_arg))) + return 0; + + /* If constructor expects vector (AltiVec) arguments, give up. */ + for (fn_parm = DECL_ARGUMENTS( fn); fn_parm; fn_parm = TREE_CHAIN (fn_parm)) + if (TREE_CODE (fn_parm) == VECTOR_TYPE) + return 0; + + /* If we don't see a clone, nothing to do. */ + clone = TREE_CHAIN (fn); + if (!clone || ! DECL_CLONED_FUNCTION_P (clone)) + return 0; + + /* This is only a win if there are two or more clones. */ + if ( ! TREE_CHAIN (clone)) + return 0; + + /* Only thunk-ify non-trivial structors. */ + if (DECL_ESTIMATED_INSNS (fn) < 5) + return 0; + + /* If we got this far, we've decided to turn the clones into thunks. */ + + /* We're going to generate code for fn, so it is no longer "abstract." */ + /* APPLE LOCAL begin 3271957 and 3262497 */ + /* Leave 'abstract' bit set for unified constructs and destructors when + -gused is used. */ + if (!(flag_debug_only_used_symbols + && DECL_DESTRUCTOR_P (fn) + && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) + && !(flag_debug_only_used_symbols + && DECL_CONSTRUCTOR_P (fn) + && DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)) + ) + DECL_ABSTRACT (fn) = 0; + /* APPLE LOCAL end 3271957 and 3262497 */ + + /* Find the vtt_parm, if present. */ + for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn); + fn_parm; + ++parmno, fn_parm = TREE_CHAIN (fn_parm)) + { + if (DECL_ARTIFICIAL (fn_parm) && DECL_NAME (fn_parm) == vtt_parm_identifier) + { + vtt_parmno = parmno; /* Compensate for removed in_charge parameter. */ + break; + } + } + + /* We know that any clones immediately follow FN in the TYPE_METHODS + list. */ + for (clone = start = TREE_CHAIN (fn); + clone && DECL_CLONED_FUNCTION_P (clone); + clone = TREE_CHAIN (clone)) + { + tree clone_parm, parmlist; + + /* If the clone and original parmlists are identical, turn the clone into an alias. */ + if (maybe_alias_body (fn, clone)) + continue; + + /* If we've already generated a body for this clone, avoid duplicating it. + (Is it possible for a clone-list to grow after we first see it?) */ + if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone)) + continue; + + /* Start processing the function. */ + push_to_top_level (); + start_function (NULL_TREE, clone, NULL_TREE, SF_PRE_PARSED); + + /* Walk parameter lists together, creating parameter list for call to original function. */ + for (parmno = 0, + parmlist = NULL, + fn_parm = DECL_ARGUMENTS (fn), + fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)), + clone_parm = DECL_ARGUMENTS (clone); + fn_parm; + ++parmno, + fn_parm = TREE_CHAIN (fn_parm)) + { + if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone)) + { + tree typed_null_pointer_node = copy_node (null_pointer_node); + my_friendly_assert (fn_parm_typelist, 0); + /* Clobber actual parameter with formal parameter type. */ + TREE_TYPE (typed_null_pointer_node) = TREE_VALUE (fn_parm_typelist); + parmlist = tree_cons (NULL, typed_null_pointer_node, parmlist); + } + else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn)) + { + tree in_charge = copy_node (in_charge_arg_for_name (DECL_NAME (clone))); + parmlist = tree_cons (NULL, in_charge, parmlist); + } + /* Map other parameters to their equivalents in the cloned + function. */ + else + { + my_friendly_assert (clone_parm, 0); + DECL_ABSTRACT_ORIGIN (clone_parm) = NULL; + parmlist = tree_cons (NULL, clone_parm, parmlist); + clone_parm = TREE_CHAIN (clone_parm); + } + if (fn_parm_typelist) + fn_parm_typelist = TREE_CHAIN (fn_parm_typelist); + } + + /* We built this list backwards; fix now. */ + parmlist = nreverse (parmlist); + mark_used (fn); + call = build_function_call (fn, parmlist); + expr_stmt = build_stmt (EXPR_STMT, call); + add_stmt (expr_stmt); + + /* Now, expand this function into RTL, if appropriate. */ + finish_function (0); + DECL_ABSTRACT_ORIGIN (clone) = NULL; + expand_body (clone); + pop_from_top_level (); + } + return 1; +} +/* APPLE LOCAL end structor thunks */ + /* FN is a function that has a complete body. Clone the body as necessary. Returns nonzero if there's no longer any need to process the main body. */ @@ -121,8 +284,7 @@ maybe_clone_body (tree fn) { tree parm; tree clone_parm; - int parmno; - splay_tree decl_map; + /* APPLE LOCAL structor thunks */ /* Update CLONE's source position information to match FN's. */ DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn); @@ -138,6 +300,8 @@ maybe_clone_body (tree fn) DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn); TREE_PUBLIC (clone) = TREE_PUBLIC (fn); DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn); + /* APPLE LOCAL coalescing */ + DECL_COALESCED (clone) = DECL_COALESCED (fn); /* Adjust the parameter names and locations. */ parm = DECL_ARGUMENTS (fn); @@ -156,6 +320,28 @@ maybe_clone_body (tree fn) parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm)) /* Update this parameter. */ update_cloned_parm (parm, clone_parm); + /* APPLE LOCAL structor thunks */ + } + + /* APPLE LOCAL begin structor thunks */ + /* If we decide to turn clones into thunks, they will branch to fn. + Must have original function available to call. */ + if (maybe_thunk_body (fn)) + return 0; + /* APPLE LOCAL end structor thunks */ + + /* APPLE LOCAL begin structor thunks */ + /* We know that any clones immediately follow FN in the TYPE_METHODS + list. */ + for (clone = TREE_CHAIN (fn); + clone && DECL_CLONED_FUNCTION_P (clone); + clone = TREE_CHAIN (clone)) + { + tree parm; + tree clone_parm; + int parmno; + splay_tree decl_map; + /* APPLE LOCAL end structor thunks */ /* Start processing the function. */ push_to_top_level (); @@ -215,6 +401,10 @@ maybe_clone_body (tree fn) /* Clone the body. */ clone_body (clone, fn, decl_map); + /* There are as many statements in the clone as in the + original. */ + DECL_ESTIMATED_INSNS (clone) = DECL_ESTIMATED_INSNS (fn); + /* Clean up. */ splay_tree_delete (decl_map); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8a51a247289..826edc3f4d6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11121,6 +11121,12 @@ instantiate_decl (tree d, int defer_ok) /* Regenerate the declaration in case the template has been modified by a subsequent redeclaration. */ regenerate_decl_from_template (d, td); + + /* APPLE LOCAL begin coalescing */ +#ifdef MARK_TEMPLATE_COALESCED + MARK_TEMPLATE_COALESCED (d); +#endif + /* APPLE LOCAL end coalescing */ /* We already set the file and line above. Reset them now in case they changed as a result of calling regenerate_decl_from_template. */ diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index a2750b220c2..133ebe4fd36 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -760,6 +760,15 @@ tinfo_base_init (tree desc, tree target) TREE_STATIC (name_decl) = 1; DECL_EXTERNAL (name_decl) = 0; TREE_PUBLIC (name_decl) = 1; + comdat_linkage (name_decl); + /* APPLE LOCAL begin coalescing */ + /* coalesce typeinfo */ +#ifdef MAKE_DECL_COALESCED + if (!typeinfo_in_lib_p (target)) + MAKE_DECL_COALESCED (name_decl); +#endif /* MAKE_DECL_COALESCED */ + /* APPLE LOCAL end coalescing */ + import_export_tinfo (name_decl, target, typeinfo_in_lib_p (target)); /* External name of the string containing the type's name has a special name. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2c232f389cb..35287bd570a 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -35,6 +35,16 @@ Boston, MA 02111-1307, USA. */ #include "tree-inline.h" #include "target.h" +/* APPLE LOCAL begin new tree dump */ +#ifdef ENABLE_DMP_TREE +#include "dmp-tree.h" +extern int cp_dump_tree_p PARAMS ((FILE *, const char *, tree, int)); +extern lang_dump_tree_p_t cp_prev_lang_dump_tree_p; +extern int c_dump_tree_p PARAMS ((FILE *, const char *, tree, int)); +extern lang_dump_tree_p_t c_prev_lang_dump_tree_p; +#endif +/* APPLE LOCAL end new tree dump */ + static tree bot_manip (tree *, int *, void *); static tree bot_replace (tree *, int *, void *); static tree build_cplus_array_type_1 (tree, tree); @@ -1767,10 +1777,8 @@ pod_type_p (tree t) return 1; /* pointer to non-member */ if (TYPE_PTR_TO_MEMBER_P (t)) return 1; /* pointer to member */ - if (TREE_CODE (t) == VECTOR_TYPE) return 1; /* vectors are (small) arrays if scalars */ - if (! CLASS_TYPE_P (t)) return 0; /* other non-class type (reference or function) */ if (CLASSTYPE_NON_POD_P (t)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 40988c7c807..77463544c90 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1058,6 +1058,17 @@ comptypes (tree t1, tree t2, int strict) case COMPLEX_TYPE: return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)); + case VECTOR_TYPE: + /* This is a comparison of types. If both of them are opaque, + the types are identical as long as their size is equal; else + check if the underlying types are identical as well. */ + return TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2) + && (targetm.vector_opaque_p (t1) + ? targetm.vector_opaque_p (t2) + : !targetm.vector_opaque_p (t2) + && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))); + break; + default: break; } @@ -1996,6 +2007,8 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name) routine directly because it expects the object to be of class type. */ ptrmem_type = TREE_TYPE (ptrmem); + /* APPLE LOCAL 2.95-ptmf-compatibility */ + if (!flag_apple_kext) my_friendly_assert (TYPE_PTRMEMFUNC_P (ptrmem_type), 20020804); member = lookup_member (ptrmem_type, member_name, /*protect=*/0, /*want_type=*/false); @@ -2278,7 +2291,10 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function))) { - tree idx, delta, e1, e2, e3, vtbl, basetype; + /* APPLE LOCAL begin 2.95-ptmf-compatibility */ + tree idx, delta, e1, e2, e3, vtbl = vtbl, basetype; + /* APPLE LOCAL 2.95-ptmf-compatibility turly 20020314 */ + tree delta2 = delta2; tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function)); tree instance_ptr = *instance_ptrptr; @@ -2310,6 +2326,17 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) /* Start by extracting all the information from the PMF itself. */ e3 = PFN_FROM_PTRMEMFUNC (function); delta = build_ptrmemfunc_access_expr (function, delta_identifier); + + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + if (flag_apple_kext) + { + idx = build_ptrmemfunc_access_expr (function, index_identifier); + idx = save_expr (default_conversion (idx)); + e1 = cp_build_binary_op (GE_EXPR, idx, integer_zero_node); + } + else + { + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ idx = build1 (NOP_EXPR, vtable_index_type, e3); switch (TARGET_PTRMEMFUNC_VBIT_LOCATION) { @@ -2327,6 +2354,19 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) abort (); } + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + } + /* DELTA2 is the amount by which to adjust the `this' pointer + to find the vtbl. */ + if (flag_apple_kext) + { + delta2 = build_ptrmemfunc_access_expr (function, + pfn_or_delta2_identifier); + delta2 = build_ptrmemfunc_access_expr (delta2, + delta2_identifier); + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ + /* Convert down to the right base before using the instance. First use the type... */ basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)); @@ -2335,6 +2375,14 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1); if (instance_ptr == error_mark_node) return error_mark_node; + + /* APPLE LOCAL begin 2.95-ptmf-compatibility */ + if (flag_apple_kext) + /* Next extract the vtable pointer from the object. */ + vtbl = build (PLUS_EXPR,build_pointer_type (vtbl_ptr_type_node), + instance_ptr, cp_convert (ptrdiff_type_node, delta2)); + /* APPLE LOCAL end 2.95-ptmf-compatibility */ + /* ...and then the delta in the PMF. */ instance_ptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr), instance_ptr, delta); @@ -2342,11 +2390,28 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function) /* Hand back the adjusted 'this' argument to our caller. */ *instance_ptrptr = instance_ptr; + /* APPLE LOCAL 2.95-ptmf-compatibility */ + if (!flag_apple_kext) /* Next extract the vtable pointer from the object. */ vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node), instance_ptr); vtbl = build_indirect_ref (vtbl, NULL); + /* APPLE LOCAL double destructor turly 20020301 */ +#ifdef ADJUST_VTABLE_INDEX + /* vptr hack already compensated for! */ + if (0) ADJUST_VTABLE_INDEX (idx, vtbl); +#endif + + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + /* 2.95-style indices are off by one. */ + if (flag_apple_kext) + { + idx = cp_build_binary_op (MINUS_EXPR, idx, integer_one_node); + idx = cp_build_binary_op (LSHIFT_EXPR, idx, integer_two_node); + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ + /* Finally, extract the function pointer from the vtable. */ e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx)); e2 = build_indirect_ref (e2, NULL); @@ -3011,6 +3076,13 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, } else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1)) { + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020314 */ + /* Shouldn't we use INDEX here rather than PFN? This seems to + work fine, though... */ + if (flag_apple_kext) + op0 = build_ptrmemfunc_access_expr (op0, index_identifier); + else + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020314 */ op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier); op1 = cp_convert (TREE_TYPE (op0), integer_zero_node); result_type = TREE_TYPE (op0); @@ -4364,8 +4436,12 @@ tree build_compound_expr (tree lhs, tree rhs) { lhs = decl_constant_value (lhs); - lhs = convert_to_void (lhs, "left-hand operand of comma"); - + /* APPLE LOCAL begin AltiVec */ + lhs = convert_to_void (lhs, targetm.cast_expr_as_vector_init + ? NULL + : "left-hand operand of comma"); + /* APPLE LOCAL end AltiVec */ + if (lhs == error_mark_node || rhs == error_mark_node) return error_mark_node; @@ -4409,6 +4485,13 @@ build_static_cast (tree type, tree expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; + /* APPLE LOCAL begin AltiVec */ + /* If we are casting to a vector type, treat the expression as a vector + initializer if this target supports it. */ + if (TREE_CODE (type) == VECTOR_TYPE && targetm.cast_expr_as_vector_init) + return vector_constructor_from_expr (expr, type); + /* APPLE LOCAL end AltiVec */ + if (processing_template_decl) { expr = build_min (STATIC_CAST_EXPR, type, expr); @@ -4598,6 +4681,13 @@ build_reinterpret_cast (tree type, tree expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; + /* APPLE LOCAL begin AltiVec */ + /* If we are casting to a vector type, treat the expression as a vector + initializer if this target supports it. */ + if (TREE_CODE (type) == VECTOR_TYPE && targetm.cast_expr_as_vector_init) + return vector_constructor_from_expr (expr, type); + /* APPLE LOCAL end AltiVec */ + if (processing_template_decl) { tree t = build_min (REINTERPRET_CAST_EXPR, type, expr); @@ -4675,6 +4765,14 @@ build_reinterpret_cast (tree type, tree expr) intype, type); return error_mark_node; } + + /* APPLE LOCAL begin don't sign-extend pointers cast to integers */ + if (TREE_CODE (type) == INTEGER_TYPE + && TREE_CODE (intype) == POINTER_TYPE + && TYPE_PRECISION (type) > TYPE_PRECISION (intype) + && TREE_UNSIGNED (type)) + expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 1), expr); + /* APPLE LOCAL end don't sign-extend pointers cast to integers */ return cp_convert (type, expr); } @@ -4760,6 +4858,13 @@ build_c_cast (tree type, tree expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; + /* APPLE LOCAL begin AltiVec */ + /* If we are casting to a vector type, treat the expression as a vector + initializer if this target supports it. */ + if (TREE_CODE (type) == VECTOR_TYPE && targetm.cast_expr_as_vector_init) + return vector_constructor_from_expr (expr, type); + /* APPLE LOCAL end AltiVec */ + if (processing_template_decl) { tree t = build_min (CAST_EXPR, type, @@ -4876,6 +4981,16 @@ build_c_cast (tree type, tree expr) value = decl_constant_value (value); + /* APPLE LOCAL begin don't sign-extend pointers cast to integers */ + if (TREE_CODE (type) == INTEGER_TYPE + && TREE_CODE (otype) == POINTER_TYPE + && TYPE_PRECISION (type) > TYPE_PRECISION (otype) + && TREE_UNSIGNED (type)) + value = convert_force (c_common_type_for_size (POINTER_SIZE, 1), + value, + CONV_C_CAST); + /* APPLE LOCAL end don't sign-extend pointers cast to integers */ + ovalue = value; value = convert_force (type, value, CONV_C_CAST); @@ -5076,6 +5191,49 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) 20011220); } + /* Handle a cast used as an "lvalue". + We have already performed any binary operator using the value as cast. + Now convert the result to the cast type of the lhs, + and then true type of the lhs and store it there; + then convert result back to the cast type to be the value + of the assignment. */ + + switch (TREE_CODE (lhs)) + { + case NOP_EXPR: + case CONVERT_EXPR: + case FLOAT_EXPR: + case FIX_TRUNC_EXPR: + case FIX_FLOOR_EXPR: + case FIX_ROUND_EXPR: + case FIX_CEIL_EXPR: + { + tree inner_lhs = TREE_OPERAND (lhs, 0); + tree result; + + if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (newrhs)) == METHOD_TYPE + || TREE_CODE (TREE_TYPE (newrhs)) == OFFSET_TYPE) + newrhs = decay_conversion (newrhs); + + /* ISO C++ 5.4/1: The result is an lvalue if T is a reference + type, otherwise the result is an rvalue. */ + if (! lvalue_p (lhs)) + pedwarn ("ISO C++ forbids cast to non-reference type used as lvalue"); + + result = build_modify_expr (inner_lhs, NOP_EXPR, + cp_convert (TREE_TYPE (inner_lhs), + cp_convert (lhstype, newrhs))); + if (result == error_mark_node) + return result; + return cp_convert (TREE_TYPE (lhs), result); + } + + default: + break; + } + /* The left-hand side must be an lvalue. */ if (!lvalue_or_else (lhs, "assignment")) return error_mark_node; @@ -5292,6 +5450,106 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn) tree delta_field; tree pfn_field; + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + if (flag_apple_kext) + { + /* Ooo-err, Missus. Cons up a 2.95-style ptmf struct given + gcc3-style inputs! Recall: + + struct ptmf2 { struct ptmf3 { + short __delta; __P __pfn; + short __index; ptrdiff_t __delta; + union { } + __P __pfn; + short __delta2; + } + } + + Won't this be fun. Much of this is snarfed from 2.95. + Note that the __delta2 val, if required, will always be __delta. */ + + tree subtype, pfn_or_delta2_field, idx, idx_field, delta2_field; + tree delta2 = integer_zero_node; + int ixval = 0; + int allconstant = 0, allsimple = 0; + + delta_field = TYPE_FIELDS (type); + idx_field = TREE_CHAIN (delta_field); + pfn_or_delta2_field = TREE_CHAIN (idx_field); + subtype = TREE_TYPE (pfn_or_delta2_field); + pfn_field = TYPE_FIELDS (subtype); + delta2_field = TREE_CHAIN (pfn_field); + + if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn) + { + /* If the low bit of PFN is set, the virtual index is PFN >> 1. + Else it's nonvirtual. */ + allconstant = TREE_CONSTANT (pfn); + allsimple = !! initializer_constant_valid_p (pfn, TREE_TYPE (pfn)); + if (TREE_CODE (pfn) == INTEGER_CST && (TREE_INT_CST_LOW (pfn) & 1)) + { + /* It's a virtual function. PFN is the vt offset + 1. */ + + int vt_entry_sz = 4; + tree vt_entry_sz_tree = TYPE_SIZE_UNIT (vtable_entry_type); + if (TREE_CODE (vt_entry_sz_tree) == INTEGER_CST) + vt_entry_sz = TREE_INT_CST_LOW (vt_entry_sz_tree); + + ixval = (TREE_INT_CST_LOW (pfn) - 1); + ixval /= vt_entry_sz; + + /* Now add 2 for that spadgey VPTR index hack, plus one because + 2.95 indices are offset by 1. */ + ixval += 2 + 1; + + /* __delta2 is the same as __delta. */ + u = tree_cons (delta2_field, delta, NULL_TREE); + } + else + if (TREE_CODE (pfn) == INTEGER_CST && TREE_INT_CST_LOW (pfn) == 0) + { + /* NULL pfn. Just zero out everything. */ + ixval = 0; + pfn = integer_zero_node; + delta = integer_zero_node; + u = tree_cons (pfn_field, pfn, NULL_TREE); + } + else + { + ixval = -1; /* -1 ==> PFN is the pointer */ + u = tree_cons (pfn_field, pfn, NULL_TREE); + } + } + else /* Low bit of DELTA is set if we're virtual. */ + { + /* Don't know how to do this yet. Much like the above, probably. */ + abort (); + allconstant = TREE_CONSTANT (delta); + allsimple = !! initializer_constant_valid_p (delta, + TREE_TYPE (delta)); + + u = tree_cons (delta2_field, delta2, NULL_TREE); + } + + delta = convert_and_check (delta_type_node, delta); + idx = convert_and_check (delta_type_node, ssize_int (ixval)); + + allconstant = allconstant && TREE_CONSTANT (delta) && TREE_CONSTANT (idx); + allsimple = allsimple + && initializer_constant_valid_p (delta, TREE_TYPE (delta)) + && initializer_constant_valid_p (idx, TREE_TYPE (idx)); + + u = build (CONSTRUCTOR, subtype, NULL_TREE, u); + u = tree_cons (delta_field, delta, + tree_cons (idx_field, idx, + tree_cons (pfn_or_delta2_field, u, NULL_TREE))); + u = build (CONSTRUCTOR, type, NULL_TREE, u); + TREE_CONSTANT (u) = allconstant; + TREE_STATIC (u) = allconstant && allsimple; + return u; + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ + /* Pull the FIELD_DECLs out of the type. */ pfn_field = TYPE_FIELDS (type); delta_field = TREE_CHAIN (pfn_field); @@ -5475,6 +5733,22 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn) tree pfn_from_ptrmemfunc (tree t) { + /* APPLE LOCAL begin 2.95-ptmf-compatibility turly 20020313 */ + if (flag_apple_kext) + { + if (TREE_CODE (t) == PTRMEM_CST) + { + tree fn = PTRMEM_CST_MEMBER (t); + if (!DECL_VIRTUAL_P (fn)) + return convert (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)), + build_addr_func (fn)); + } + + t = build_ptrmemfunc_access_expr (t, pfn_or_delta2_identifier); + return build_ptrmemfunc_access_expr (t, pfn_identifier); + } + /* APPLE LOCAL end 2.95-ptmf-compatibility turly 20020313 */ + if (TREE_CODE (t) == PTRMEM_CST) { tree delta; @@ -5562,8 +5836,7 @@ convert_for_assignment (tree type, tree rhs, coder = TREE_CODE (rhstype); if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE - && ((*targetm.vector_opaque_p) (type) - || (*targetm.vector_opaque_p) (rhstype))) + && vector_types_compatible_p (type, rhstype)) return convert (type, rhs); if (rhs == error_mark_node || rhstype == error_mark_node) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index f0717f60884..3edf58313aa 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -555,13 +555,21 @@ digest_init (tree type, tree init, tree* tail) if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) != char_type_node) + /* APPLE LOCAL begin Pascal strings 2001-07-05 zll */ + && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) + != unsigned_char_type_node) + /* APPLE LOCAL end Pascal strings 2001-07-05 zll */ && TYPE_PRECISION (typ1) == BITS_PER_UNIT) { error ("char-array initialized from wide string"); return error_mark_node; } - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) + /* APPLE LOCAL begin Pascal strings 2001-07-05 zll */ + if (((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) == char_type_node) + || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) + == unsigned_char_type_node)) + /* APPLE LOCAL end Pascal strings 2001-07-05 zll */ && TYPE_PRECISION (typ1) != BITS_PER_UNIT) { error ("int-array initialized from non-wide string"); |