From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19953 invoked by alias); 11 Mar 2011 04:24:27 -0000 Received: (qmail 19510 invoked by uid 22791); 11 Mar 2011 04:24:21 -0000 X-SWARE-Spam-Status: No, hits=-0.6 required=5.0 tests=AWL,BAYES_40,TW_BJ,TW_CX,TW_FN,TW_SF,T_FILL_THIS_FORM_SHORT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 11 Mar 2011 04:24:11 +0000 Received: (qmail 1834 invoked from network); 11 Mar 2011 04:24:08 -0000 Received: from unknown (HELO codesourcery.com) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 11 Mar 2011 04:24:08 -0000 From: Nathan Froyd To: gcc-patches@gcc.gnu.org Cc: Nathan Froyd , jason@redhat.com Subject: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier Date: Fri, 11 Mar 2011 04:24:00 -0000 Message-Id: <1299817406-16745-16-git-send-email-froydnj@codesourcery.com> In-Reply-To: <1299817406-16745-1-git-send-email-froydnj@codesourcery.com> References: <1299817406-16745-1-git-send-email-froydnj@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-03/txt/msg00554.txt.bz2 IDENTIFIER_NODE is next up for a shrinking. To do that, though, we have to do some surgery on the C++ FE, as it uses TREE_TYPE (!) of such nodes to store local data. Fortunately, we can move that information into lang_identifier; unfortunately, that means we need to introduce a number of conditionals because the punning of TREE_TYPE no longer works. On the plus side, it's much more obvious where REAL_IDENTIFIER_TYPE_VALUE was supposed to be used, as it was used inconsistently before. I'm not overly fond of the conditionals (especially in error_operand_p) but I don't think it's reasonable to make IDENTIFIER_NODE bigger and penalize the other FEs just because the C++ FE is playing games with TREE_TYPE. I'm open to suggestions of how to avoid some of the ugliness. There's also one small potential problem with doing this that I'll mention in the next patch. -Nathan gcc/cp/ * cp-tree.h (struct lang_identifier): Add local_class_scope_type field. (REAL_IDENTIFIER_TYPE_VALUE): Use that field, rather than TREE_TYPE. (SET_IDENTIFIER_TYPE_VALUE): Use REAL_IDENTIFIER_TYPE_VALUE rather than TREE_TYPE. (error_operand_p): Make special check for IDENTIFIER_NODE. (DECL_CONV_FN_TYPE): Use REAL_IDENTIFIER_TYPE_VALUE. * decl.c (cp_finish_decl, grok_op_properties): Likewise. (compute_array_index_type): Check for IDENTIFIER_NODE. * decl2.c (constrain_visibility_for_template): Likewise. (determine_visibility): Use REAL_IDENTIFIER_TYPE_VALUE. (import_export_decl): Likewise. * error.c (dump_decl): Likewise. * mangle.c (write_template_prefix): Check for IDENTIFIER_NODE. Refactor to only check once. (write_unqualified_id): Use REAL_IDENTIFIER_TYPE_VALUE. (hash_type): Likewise. (compare_type): Likewise. (mangle_conv_op_name_for_type): Likewise. * name-lookup.c (do_class_using_decl): Likewise. (find_parameter_packs_r): Likewise. (lookup_template_function): Check for IDENTIFIER_NODE. (any_template_arguments_need_structural_equality_p): Likewise. (tsubst_identifier): New function. (tsubst_copy, tsubst_copy_and_build): Call it. * repo.c (repo_emit_p): Use REAL_IDENTIFIER_TYPE_VALUE. * rtti.c (get_tinfo_decl, tinfo_base_init): Likewise. (emit_tinfo_decl): Likewise. * search.c (lookup_fnfields_1): Likewise. (lookup_member): Check for IDENTIFIER_NODE. * semantics.c (finish_id_expression): Use REAL_IDENTIFIER_TYPE_VALUE. (finish_id_expression): Check for IDENTIFIER_NODE. * typeck.c (finish_class_member_access_expr): Likewise. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fd28593..a3e59b0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -222,6 +222,7 @@ struct GTY(()) lang_identifier { cxx_binding *bindings; tree class_template_info; tree label_value; + tree local_class_scope_type; }; /* In an IDENTIFIER_NODE, nonzero if this identifier is actually a @@ -448,13 +449,15 @@ typedef enum impl_conv_void { #define IDENTIFIER_BINDING(NODE) \ (LANG_IDENTIFIER_CAST (NODE)->bindings) -/* TREE_TYPE only indicates on local and class scope the current - type. For namespace scope, the presence of a type in any namespace - is indicated with global_type_node, and the real type behind must - be found through lookup. */ +/* For namespace scope, the presence of a type in any namespace is + indicated with global_type_node, and the real type behind must be + found through lookup. For local and class scope, we can grab the + type from the identifier directly. */ #define IDENTIFIER_TYPE_VALUE(NODE) identifier_type_value (NODE) -#define REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE) -#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE)) +#define REAL_IDENTIFIER_TYPE_VALUE(NODE) \ + (LANG_IDENTIFIER_CAST (NODE)->local_class_scope_type) +#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) \ + (REAL_IDENTIFIER_TYPE_VALUE (NODE) = (TYPE)) #define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0) #define IDENTIFIER_LABEL_VALUE(NODE) \ @@ -1104,7 +1107,10 @@ struct GTY(()) language_function { #define error_operand_p(NODE) \ ((NODE) == error_mark_node \ - || ((NODE) && TREE_TYPE ((NODE)) == error_mark_node)) + || ((NODE) \ + && ((TREE_CODE (NODE) == IDENTIFIER_NODE \ + ? REAL_IDENTIFIER_TYPE_VALUE (NODE) \ + : TREE_TYPE (NODE)) == error_mark_node))) /* TRUE if a tree code represents a statement. */ extern bool statement_code_p[MAX_TREE_CODES]; @@ -2121,8 +2127,10 @@ struct GTY((variable_size)) lang_decl { /* If FN is a conversion operator, the type to which it converts. Otherwise, NULL_TREE. */ -#define DECL_CONV_FN_TYPE(FN) \ - (DECL_CONV_FN_P (FN) ? TREE_TYPE (DECL_NAME (FN)) : NULL_TREE) +#define DECL_CONV_FN_TYPE(FN) \ + (DECL_CONV_FN_P (FN) \ + ? REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (FN)) \ + : NULL_TREE) /* Nonzero if NODE, which is a TEMPLATE_DECL, is a template conversion operator to a type dependent on the innermost template diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e1e6fe2..a0ef39f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5897,7 +5897,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (type != error_mark_node && MAYBE_CLASS_TYPE_P (type) && DECL_NAME (decl)) { - if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type) + if (REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl)) + && TREE_TYPE (decl) != type) warning (0, "shadowing previous type declaration of %q#D", decl); set_identifier_type_value (DECL_NAME (decl), decl); } @@ -7501,7 +7502,10 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) if (error_operand_p (size)) return error_mark_node; - type = TREE_TYPE (size); + type = (TREE_CODE (size) == IDENTIFIER_NODE + ? REAL_IDENTIFIER_TYPE_VALUE (size) + : TREE_TYPE (size)); + /* type_dependent_expression_p? */ if (!dependent_type_p (type)) { @@ -8124,7 +8128,7 @@ grokdeclarator (const cp_declarator *declarator, { gcc_assert (flags == NO_SPECIAL); flags = TYPENAME_FLAG; - ctor_return_type = TREE_TYPE (dname); + ctor_return_type = REAL_IDENTIFIER_TYPE_VALUE (dname); sfk = sfk_conversion; if (is_typename_at_global_scope (dname)) name = identifier_to_locale (IDENTIFIER_POINTER (dname)); @@ -10707,7 +10711,7 @@ grok_op_properties (tree decl, bool complain) warn again about out-of-class definitions. */ && class_type == current_class_type) { - tree t = TREE_TYPE (name); + tree t = REAL_IDENTIFIER_TYPE_VALUE (name); int ref = (TREE_CODE (t) == REFERENCE_TYPE); if (ref) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index fa114ba..ce73229 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1964,7 +1964,10 @@ constrain_visibility_for_template (tree decl, tree targs) tree arg = TREE_VEC_ELT (args, i-1); if (TYPE_P (arg)) vis = type_visibility (arg); - else if (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg))) + else if (TREE_CODE (arg) == IDENTIFIER_NODE + ? (REAL_IDENTIFIER_TYPE_VALUE (arg) + && POINTER_TYPE_P (REAL_IDENTIFIER_TYPE_VALUE (arg))) + : (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))) { STRIP_NOPS (arg); if (TREE_CODE (arg) == ADDR_EXPR) @@ -2072,7 +2075,7 @@ determine_visibility (tree decl) { /* Under -fvisibility-ms-compat, types are visible by default, even though their contents aren't. */ - tree underlying_type = TREE_TYPE (DECL_NAME (decl)); + tree underlying_type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl)); int underlying_vis = type_visibility (underlying_type); if (underlying_vis == VISIBILITY_ANON || (CLASS_TYPE_P (underlying_type) @@ -2083,16 +2086,17 @@ determine_visibility (tree decl) } else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl)) { + tree id_type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl)); + /* tinfo visibility is based on the type it's for. */ - constrain_visibility - (decl, type_visibility (TREE_TYPE (DECL_NAME (decl)))); + constrain_visibility (decl, type_visibility (id_type)); /* Give the target a chance to override the visibility associated with DECL. */ if (TREE_PUBLIC (decl) && !DECL_REALLY_EXTERN (decl) - && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl))) - && !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl)))) + && CLASS_TYPE_P (id_type) + && !CLASSTYPE_VISIBILITY_SPECIFIED (id_type)) targetm.cxx.determine_class_data_visibility (decl); } else if (use_template) @@ -2449,7 +2453,7 @@ import_export_decl (tree decl) } else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl)) { - tree type = TREE_TYPE (DECL_NAME (decl)); + tree type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl)); if (CLASS_TYPE_P (type)) { class_type = type; diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 28305d2..50a846f 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1011,7 +1011,7 @@ dump_decl (tree t, int flags) { pp_cxx_ws_string (cxx_pp, "operator"); /* Not exactly IDENTIFIER_TYPE_VALUE. */ - dump_type (TREE_TYPE (t), flags); + dump_type (REAL_IDENTIFIER_TYPE_VALUE (t), flags); break; } else diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index e4d53c5..236248e 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -1094,16 +1094,20 @@ write_template_prefix (const tree node) if (find_substitution (substitution)) return; + type = (TREE_CODE (templ) == IDENTIFIER_NODE + ? REAL_IDENTIFIER_TYPE_VALUE (templ) + : TREE_TYPE (templ)); + /* In G++ 3.2, the name of the template template parameter was used. */ - if (TREE_TYPE (templ) - && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM + if (type + && TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM && !abi_version_at_least (2)) G.need_abi_warning = true; - if (TREE_TYPE (templ) - && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM + if (type + && TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM && abi_version_at_least (2)) - write_template_param (TREE_TYPE (templ)); + write_template_param (type); else { write_prefix (context); @@ -1128,7 +1132,7 @@ static void write_unqualified_id (tree identifier) { if (IDENTIFIER_TYPENAME_P (identifier)) - write_conversion_operator_name (TREE_TYPE (identifier)); + write_conversion_operator_name (REAL_IDENTIFIER_TYPE_VALUE (identifier)); else if (IDENTIFIER_OPNAME_P (identifier)) { int i; @@ -3321,7 +3325,8 @@ static GTY ((param_is (union tree_node))) htab_t conv_type_names; static hashval_t hash_type (const void *val) { - return (hashval_t) TYPE_UID (TREE_TYPE ((const_tree) val)); + tree t = CONST_CAST_TREE ((const_tree) val); + return (hashval_t) TYPE_UID (REAL_IDENTIFIER_TYPE_VALUE (t)); } /* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */ @@ -3329,7 +3334,8 @@ hash_type (const void *val) static int compare_type (const void *val1, const void *val2) { - return TREE_TYPE ((const_tree) val1) == (const_tree) val2; + return (REAL_IDENTIFIER_TYPE_VALUE (CONST_CAST_TREE ((const_tree) val1)) + == CONST_CAST_TREE ((const_tree) val2)); } /* Return an identifier for the mangled unqualified name for a @@ -3363,7 +3369,7 @@ mangle_conv_op_name_for_type (const tree type) /* Hang TYPE off the identifier so it can be found easily later when performing conversions. */ - TREE_TYPE (identifier) = type; + REAL_IDENTIFIER_TYPE_VALUE (identifier) = type; /* Set bits on the identifier so we know later it's a conversion. */ IDENTIFIER_OPNAME_P (identifier) = 1; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b5472de..d585ddc 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3001,7 +3001,7 @@ do_class_using_decl (tree scope, tree name) scope_dependent_p = dependent_type_p (scope); name_dependent_p = (scope_dependent_p || (IDENTIFIER_TYPENAME_P (name) - && dependent_type_p (TREE_TYPE (name)))); + && dependent_type_p (REAL_IDENTIFIER_TYPE_VALUE (name)))); bases_dependent_p = false; if (processing_template_decl) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8d28219..63445b2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3040,8 +3040,8 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) return NULL_TREE; case IDENTIFIER_NODE: - cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, - ppd->visited); + cp_walk_tree (&REAL_IDENTIFIER_TYPE_VALUE (t), &find_parameter_packs_r, + ppd, ppd->visited); *walk_subtrees = 0; return NULL_TREE; @@ -6600,7 +6600,9 @@ lookup_template_function (tree fns, tree arglist) return fns; } - type = TREE_TYPE (fns); + type = (TREE_CODE (fns) == IDENTIFIER_NODE + ? REAL_IDENTIFIER_TYPE_VALUE (fns) + : TREE_TYPE (fns)); if (TREE_CODE (fns) == OVERLOAD || !type) type = unknown_type_node; @@ -11246,6 +11248,21 @@ tsubst_qualified_id (tree qualified_id, tree args, return expr; } +/* tsubst for IDENTIFIER_NODEs. */ + +static tree +tsubst_identifier (tree t, tree args, tsubst_flags_t complain, tree in_decl) +{ + if (IDENTIFIER_TYPENAME_P (t)) + { + tree new_type = tsubst (REAL_IDENTIFIER_TYPE_VALUE (t), + args, complain, in_decl); + return mangle_conv_op_name_for_type (new_type); + } + else + return t; +} + /* Like tsubst, but deals with expressions. This function just replaces template parms; to finish processing the resultant expression, use tsubst_expr. */ @@ -11660,13 +11677,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return tsubst (t, args, complain, in_decl); case IDENTIFIER_NODE: - if (IDENTIFIER_TYPENAME_P (t)) - { - tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); - return mangle_conv_op_name_for_type (new_type); - } - else - return t; + return tsubst_identifier (t, args, complain, in_decl); case CONSTRUCTOR: /* This is handled by tsubst_copy_and_build. */ @@ -12477,11 +12488,7 @@ tsubst_copy_and_build (tree t, bool non_integral_constant_expression_p; const char *error_msg; - if (IDENTIFIER_TYPENAME_P (t)) - { - tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); - t = mangle_conv_op_name_for_type (new_type); - } + t = tsubst_identifier (t, args, complain, in_decl); /* Look up the name. */ decl = lookup_name (t); @@ -18500,6 +18507,9 @@ any_template_arguments_need_structural_equality_p (tree args) continue; else if (TYPE_P (arg) && TYPE_STRUCTURAL_EQUALITY_P (arg)) return true; + else if (TREE_CODE (arg) == IDENTIFIER_NODE) + return (REAL_IDENTIFIER_TYPE_VALUE (arg) + && TYPE_STRUCTURAL_EQUALITY_P (REAL_IDENTIFIER_TYPE_VALUE (arg))); else if (!TYPE_P (arg) && TREE_TYPE (arg) && TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (arg))) return true; diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index 16a192e..444f884 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -309,7 +309,7 @@ repo_emit_p (tree decl) if (DECL_VTABLE_OR_VTT_P (decl)) type = DECL_CONTEXT (decl); else if (DECL_TINFO_P (decl)) - type = TREE_TYPE (DECL_NAME (decl)); + type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl)); if (!DECL_TEMPLATE_INSTANTIATION (decl) && (!TYPE_LANG_SPECIFIC (type) || !CLASSTYPE_TEMPLATE_INSTANTIATION (type))) diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 0feaf07..789a087 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -426,7 +426,7 @@ get_tinfo_decl (tree type) d = build_lang_decl (VAR_DECL, name, ti->type); SET_DECL_ASSEMBLER_NAME (d, name); /* Remember the type it is for. */ - TREE_TYPE (name) = type; + REAL_IDENTIFIER_TYPE_VALUE (name) = type; DECL_TINFO_P (d) = 1; DECL_ARTIFICIAL (d) = 1; DECL_IGNORED_P (d) = 1; @@ -876,7 +876,7 @@ tinfo_base_init (tinfo_s *ti, tree target) /* Determine the name of the variable -- and remember with which type it is associated. */ name_name = mangle_typeinfo_string_for_type (target); - TREE_TYPE (name_name) = target; + REAL_IDENTIFIER_TYPE_VALUE (name_name) = target; name_decl = build_lang_decl (VAR_DECL, name_name, name_type); SET_DECL_ASSEMBLER_NAME (name_decl, name_name); @@ -1538,7 +1538,7 @@ emit_support_tinfos (void) bool emit_tinfo_decl (tree decl) { - tree type = TREE_TYPE (DECL_NAME (decl)); + tree type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl)); int in_library = typeinfo_in_lib_p (type); gcc_assert (DECL_TINFO_P (decl)); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 188f0a5..87d6736 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1259,7 +1259,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) if (rval && is_overloaded_fn (rval)) rval = build_baselink (rval_binfo, basetype_path, rval, (IDENTIFIER_TYPENAME_P (name) - ? TREE_TYPE (name): NULL_TREE)); + ? REAL_IDENTIFIER_TYPE_VALUE (name): NULL_TREE)); return rval; } @@ -1397,7 +1397,7 @@ lookup_fnfields_1 (tree type, tree name) return fn ? CLASSTYPE_DESTRUCTOR_SLOT : -1; } if (IDENTIFIER_TYPENAME_P (name)) - return lookup_conversion_operator (type, TREE_TYPE (name)); + return lookup_conversion_operator (type, REAL_IDENTIFIER_TYPE_VALUE (name)); /* Skip the conversion operators. */ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 6c8dfd7..142dc66 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2825,7 +2825,7 @@ finish_id_expression (tree id_expression, || (!dependent_type_p (scope) && !(TREE_CODE (id_expression) == IDENTIFIER_NODE && IDENTIFIER_TYPENAME_P (id_expression) - && dependent_type_p (TREE_TYPE (id_expression)))))) + && dependent_type_p (REAL_IDENTIFIER_TYPE_VALUE (id_expression)))))) { /* If the qualifying type is non-dependent (and the name does not name a conversion operator to a dependent @@ -3029,7 +3029,9 @@ finish_id_expression (tree id_expression, type. */ else if (!is_overloaded_fn (decl)) dependent_p - = dependent_type_p (TREE_TYPE (decl)); + = dependent_type_p (TREE_CODE (decl) == IDENTIFIER_NODE + ? REAL_IDENTIFIER_TYPE_VALUE (decl) + : TREE_TYPE (decl)); /* For a set of overloaded functions, check each of the functions. */ else diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c062f0f..2fe7483 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2452,7 +2452,9 @@ finish_class_member_access_expr (tree object, tree name, bool template_p, if (!objc_is_public (object, name)) return error_mark_node; - object_type = TREE_TYPE (object); + object_type = (TREE_CODE (object) == IDENTIFIER_NODE + ? REAL_IDENTIFIER_TYPE_VALUE (object) + : TREE_TYPE (object)); if (processing_template_decl) { -- 1.7.0.4