2006-02-15 J"orn Rennecke gcc: * c-objc-common.h (LANG_HOOKS_TRY_MARK_ADDRESSABLE): Redefine. * c-tree.h (c_try_mark_addressable): Declare. * langhooks.h (struct lang_hooks): New member try_mark_addressable. * c-typeck.c (c_mark_addressable_internal): New function, broken out of: (c_mark_addressable). (c_try_mark_addressable): New function. * langhooks-def.h (LANG_HOOKS_INITIALIZE): Add LANG_HOOKS_TRY_MARK_ADDRESSABLE. gcc/cp: * typeck.c (cxx_mark_addressable_internal): New function, broken of: (cxx_mark_addressable). (cxx_try_mark_addressable): New function. * cp-objcp-common.h (LANG_HOOKS_TRY_MARK_ADDRESSABLE): Redefine. * cp-tree.h (cxx_try_mark_addressable): Declare. gcc/java: * typeck.c (java_try_mark_addressable): New function, broken out of: (java_mark_addressable). * lang.c (LANG_HOOKS_TRY_MARK_ADDRESSABLE): Redefine. * java-tree.h (java_try_mark_addressable): Declare. gcc/fortran: * f95-lang.c (LANG_HOOKS_TRY_MARK_ADDRESSABLE): Redefine. (gfc_mark_addressable_internal): New function, broken out of: (gfc_mark_addressable). (gfc_try_mark_addressable): New function. gcc/ada: * misc.c (LANG_HOOKS_TRY_MARK_ADDRESSABLE): Redefine. * utils2.c (gnat_try_mark_addressable): New function, broken out of: (gnat_mark_addressable). * gigi.h (gnat_try_mark_addressable): Declare. gcc/treelang: * treetree.c (LANG_HOOKS_TRY_MARK_ADDRESSABLE): Redefine. (tree_mark_addressable_internal): New function, broken out of: (tree_mark_addressable). (tree_try_mark_addressable): New function. Index: java/typeck.c =================================================================== /usr/bin/diff -p -d -F^( -u -L java/typeck.c (revision 110439) -L java/typeck.c (working copy) java/.svn/text-base/typeck.c.svn-base java/typeck.c --- java/typeck.c (revision 110439) +++ java/typeck.c (working copy) @@ -236,7 +236,7 @@ java_unsigned_type (tree type) Value is true if successful. */ bool -java_mark_addressable (tree exp) +java_try_mark_addressable (tree exp, bool cancel_regdecl ATTRIBUTE_UNUSED) { tree x = exp; while (1) @@ -296,6 +296,13 @@ java_mark_addressable (tree exp) } } +/* Same as above, without the unused parameter. */ +bool +java_mark_addressable (tree exp) +{ + return java_try_mark_addressable (exp, false); +} + /* Thorough checking of the arrayness of TYPE. */ int Index: java/lang.c =================================================================== /usr/bin/diff -p -d -F^( -u -L java/lang.c (revision 110439) -L java/lang.c (working copy) java/.svn/text-base/lang.c.svn-base java/lang.c --- java/lang.c (revision 110439) +++ java/lang.c (working copy) @@ -167,6 +167,8 @@ struct language_function GTY(()) #define LANG_HOOKS_POST_OPTIONS java_post_options #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE java_parse_file +#undef LANG_HOOKS_TRY_MARK_ADDRESSABLE +#define LANG_HOOKS_TRY_MARK_ADDRESSABLE java_try_mark_addressable #undef LANG_HOOKS_MARK_ADDRESSABLE #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL Index: java/java-tree.h =================================================================== /usr/bin/diff -p -d -F^( -u -L java/java-tree.h (revision 110439) -L java/java-tree.h (working copy) java/.svn/text-base/java-tree.h.svn-base java/java-tree.h --- java/java-tree.h (revision 110439) +++ java/java-tree.h (working copy) @@ -1151,6 +1151,7 @@ struct lang_type GTY(()) struct eh_range; extern void java_parse_file (int); +extern bool java_try_mark_addressable (tree, bool); extern bool java_mark_addressable (tree); extern tree java_type_for_mode (enum machine_mode, int); extern tree java_type_for_size (unsigned int, int); Index: cp/typeck.c =================================================================== /usr/bin/diff -p -d -F^( -u -L cp/typeck.c (revision 110439) -L cp/typeck.c (working copy) cp/.svn/text-base/typeck.c.svn-base cp/typeck.c --- cp/typeck.c (revision 110439) +++ cp/typeck.c (working copy) @@ -4390,11 +4390,15 @@ unary_complex_lvalue (enum tree_code cod /* Mark EXP saying that we need to be able to take the address of it; it should not be allocated in a register. Value is true if successful. + If CANCEL_REGDECL is set, ignore register declarations for local + variables / parameters unless a specific hard register was requested. + If EMIT_DIAGNOSTICS is set, emit warnings / errors. C++: we do not allow `current_class_ptr' to be addressable. */ -bool -cxx_mark_addressable (tree exp) +static bool +cxx_mark_addressable_internal (tree exp, bool cancel_regdecl, + bool emit_diagnostics) { tree x = exp; @@ -4412,9 +4416,14 @@ cxx_mark_addressable (tree exp) case PARM_DECL: if (x == current_class_ptr) { - error ("cannot take the address of %, which is an rvalue expression"); - TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later. */ - return true; + if (emit_diagnostics) + { + error ("cannot take the address of %, which is an rvalue expression"); + TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later. */ + return true; + } + else + return false; } /* Fall through. */ @@ -4434,13 +4443,17 @@ cxx_mark_addressable (tree exp) { if (TREE_CODE (x) == VAR_DECL && DECL_HARD_REGISTER (x)) { - error - ("address of explicit register variable %qD requested", x); + if (emit_diagnostics) + error + ("address of explicit register variable %qD requested", x); return false; } - else if (extra_warnings) + else if (emit_diagnostics && extra_warnings) warning - (0, "address requested for %qD, which is declared %", x); + (0, "address requested for %qD, which is declared %", + x); + if (!cancel_regdecl) + return false; } TREE_ADDRESSABLE (x) = 1; return true; @@ -4462,6 +4475,21 @@ cxx_mark_addressable (tree exp) return true; } } + +/* Likewise, but don't provide option of emitting diagnostics. */ +bool +cxx_try_mark_addressable (tree exp, bool cancel_regdecl) +{ + return cxx_mark_addressable_internal (exp, cancel_regdecl, false); +} + +/* Likewise, but always cancel register declarations unless they specify + a specific registyer, and always emit diagnostics. */ +bool +cxx_mark_addressable (tree exp) +{ + return cxx_mark_addressable_internal (exp, true, true); +} /* Build and return a conditional expression IFEXP ? OP1 : OP2. */ Index: cp/cp-objcp-common.h =================================================================== /usr/bin/diff -p -d -F^( -u -L cp/cp-objcp-common.h (revision 110439) -L cp/cp-objcp-common.h (working copy) cp/.svn/text-base/cp-objcp-common.h.svn-base cp/cp-objcp-common.h --- cp/cp-objcp-common.h (revision 110439) +++ cp/cp-objcp-common.h (working copy) @@ -63,6 +63,8 @@ extern tree objcp_tsubst_copy_and_build #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME mangle_decl +#undef LANG_HOOKS_TRY_MARK_ADDRESSABLE +#define LANG_HOOKS_TRY_MARK_ADDRESSABLE cxx_try_mark_addressable #undef LANG_HOOKS_MARK_ADDRESSABLE #define LANG_HOOKS_MARK_ADDRESSABLE cxx_mark_addressable #undef LANG_HOOKS_PRINT_STATISTICS Index: cp/cp-tree.h =================================================================== /usr/bin/diff -p -d -F^( -u -L cp/cp-tree.h (revision 110439) -L cp/cp-tree.h (working copy) cp/.svn/text-base/cp-tree.h.svn-base cp/cp-tree.h --- cp/cp-tree.h (revision 110439) +++ cp/cp-tree.h (working copy) @@ -3772,6 +3772,7 @@ extern tree pushdecl_maybe_friend (tree extern void cxx_init_decl_processing (void); enum cp_tree_node_structure_enum cp_tree_node_structure (union lang_tree_node *); +extern bool cxx_try_mark_addressable (tree, bool); extern bool cxx_mark_addressable (tree); extern void cxx_push_function_context (struct function *); extern void cxx_pop_function_context (struct function *); Index: c-objc-common.h =================================================================== /usr/bin/diff -p -d -F^( -u -L c-objc-common.h (revision 110439) -L c-objc-common.h (working copy) .svn/text-base/c-objc-common.h.svn-base c-objc-common.h --- c-objc-common.h (revision 110439) +++ c-objc-common.h (working copy) @@ -48,6 +48,8 @@ extern void c_initialize_diagnostics (di #define LANG_HOOKS_EXPAND_EXPR c_expand_expr #undef LANG_HOOKS_EXPAND_DECL #define LANG_HOOKS_EXPAND_DECL c_expand_decl +#undef LANG_HOOKS_TRY_MARK_ADDRESSABLE +#define LANG_HOOKS_TRY_MARK_ADDRESSABLE c_try_mark_addressable #undef LANG_HOOKS_MARK_ADDRESSABLE #define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable #undef LANG_HOOKS_PARSE_FILE Index: c-tree.h =================================================================== /usr/bin/diff -p -d -F^( -u -L c-tree.h (revision 110439) -L c-tree.h (working copy) .svn/text-base/c-tree.h.svn-base c-tree.h --- c-tree.h (revision 110439) +++ c-tree.h (working copy) @@ -524,6 +524,7 @@ extern struct c_label_context_vm *label_ extern tree require_complete_type (tree); extern int same_translation_unit_p (tree, tree); extern int comptypes (tree, tree); +extern bool c_try_mark_addressable (tree, bool); extern bool c_mark_addressable (tree); extern void c_incomplete_type_error (tree, tree); extern tree c_type_promotes_to (tree); Index: ada/misc.c =================================================================== /usr/bin/diff -p -d -F^( -u -L ada/misc.c (revision 110439) -L ada/misc.c (working copy) ada/.svn/text-base/misc.c.svn-base ada/misc.c --- ada/misc.c (revision 110439) +++ ada/misc.c (working copy) @@ -134,6 +134,8 @@ static tree gnat_type_max_size (tree); #define LANG_HOOKS_GET_ALIAS_SET gnat_get_alias_set #undef LANG_HOOKS_EXPAND_EXPR #define LANG_HOOKS_EXPAND_EXPR gnat_expand_expr +#undef LANG_HOOKS_TRY_MARK_ADDRESSABLE +#define LANG_HOOKS_TRY_MARK_ADDRESSABLE gnat_try_mark_addressable #undef LANG_HOOKS_MARK_ADDRESSABLE #define LANG_HOOKS_MARK_ADDRESSABLE gnat_mark_addressable #undef LANG_HOOKS_PRINT_DECL Index: ada/utils2.c =================================================================== /usr/bin/diff -p -d -F^( -u -L ada/utils2.c (revision 110439) -L ada/utils2.c (working copy) ada/.svn/text-base/utils2.c.svn-base ada/utils2.c --- ada/utils2.c (revision 110439) +++ ada/utils2.c (working copy) @@ -2012,7 +2012,8 @@ fill_vms_descriptor (tree expr, Entity_I should not be allocated in a register. Returns true if successful. */ bool -gnat_mark_addressable (tree expr_node) +gnat_try_mark_addressable (tree expr_node, + bool cancel_regdecl ATTRIBUTE_UNUSED) { while (1) switch (TREE_CODE (expr_node)) @@ -2052,3 +2053,10 @@ gnat_mark_addressable (tree expr_node) return true; } } + +/* Likewise, but without the dummy parameter. */ +bool +gnat_mark_addressable (tree expr_node) +{ + return gnat_try_mark_addressable (tree expr_node, false) +} Index: ada/gigi.h =================================================================== /usr/bin/diff -p -d -F^( -u -L ada/gigi.h (revision 110439) -L ada/gigi.h (working copy) ada/.svn/text-base/gigi.h.svn-base ada/gigi.h --- ada/gigi.h (revision 110439) +++ ada/gigi.h (working copy) @@ -756,6 +756,11 @@ extern tree build_allocator (tree type, extern tree fill_vms_descriptor (tree expr, Entity_Id gnat_formal); +/* Try to indicate that we need to make the address of EXPR_NODE and it + therefore should not be allocated in a register. Return true if + successful. */ +extern bool gnat_try_mark_addressable (tree expr_node, bool); + /* Indicate that we need to make the address of EXPR_NODE and it therefore should not be allocated in a register. Return true if successful. */ extern bool gnat_mark_addressable (tree expr_node); Index: fortran/f95-lang.c =================================================================== /usr/bin/diff -p -d -F^( -u -L fortran/f95-lang.c (revision 110439) -L fortran/f95-lang.c (working copy) fortran/.svn/text-base/f95-lang.c.svn-base fortran/f95-lang.c --- fortran/f95-lang.c (revision 110439) +++ fortran/f95-lang.c (working copy) @@ -92,6 +92,7 @@ static void gfc_init_builtin_functions ( static bool gfc_init (void); static void gfc_finish (void); static void gfc_print_identifier (FILE *, tree, int); +static bool gfc_try_mark_addressable (tree, bool); static bool gfc_mark_addressable (tree); void do_function_end (void); int global_bindings_p (void); @@ -108,6 +109,7 @@ static void gfc_expand_function (tree); #undef LANG_HOOKS_POST_OPTIONS #undef LANG_HOOKS_PRINT_IDENTIFIER #undef LANG_HOOKS_PARSE_FILE +#undef LANG_HOOKS_TRY_MARK_ADDRESSABLE #undef LANG_HOOKS_MARK_ADDRESSABLE #undef LANG_HOOKS_TYPE_FOR_MODE #undef LANG_HOOKS_TYPE_FOR_SIZE @@ -126,6 +128,7 @@ static void gfc_expand_function (tree); #define LANG_HOOKS_POST_OPTIONS gfc_post_options #define LANG_HOOKS_PRINT_IDENTIFIER gfc_print_identifier #define LANG_HOOKS_PARSE_FILE gfc_be_parse_file +#define LANG_HOOKS_TRY_MARK_ADDRESSABLE gfc_try_mark_addressable #define LANG_HOOKS_MARK_ADDRESSABLE gfc_mark_addressable #define LANG_HOOKS_TYPE_FOR_MODE gfc_type_for_mode #define LANG_HOOKS_TYPE_FOR_SIZE gfc_type_for_size @@ -612,9 +615,14 @@ gfc_init_decl_processing (void) the TARGET attribute, but we implement it here for a likely future Cray pointer extension. Value is 1 if successful. */ + If CANCEL_REGDECL is set, ignore register declarations for local + variables / parameters unless a specific hard register was requested. + If EMIT_DIAGNOSTICS is set, emit warnings / errors. /* TODO: Check/fix mark_addressable. */ -bool -gfc_mark_addressable (tree exp) +/* ??? When diagnostics are requested, we sometimes lie about the success. */ +static bool +gfc_mark_addressable_internal (tree exp, bool cancel_regdecl, + bool emit_diagnostics) { register tree x = exp; while (1) @@ -640,18 +648,22 @@ gfc_mark_addressable (tree exp) { if (TREE_PUBLIC (x)) { - error - ("global register variable %qs used in nested function", - IDENTIFIER_POINTER (DECL_NAME (x))); + if (emit_diagnostics) + error + ("global register variable %qs used in nested function", + IDENTIFIER_POINTER (DECL_NAME (x))); return false; } - pedwarn ("register variable %qs used in nested function", - IDENTIFIER_POINTER (DECL_NAME (x))); + if (emit_diagnostics) + pedwarn ("register variable %qs used in nested function", + IDENTIFIER_POINTER (DECL_NAME (x))); } else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)) { if (TREE_PUBLIC (x)) { + if (!emit_diagnostics) + return false; error ("address of global register variable %qs requested", IDENTIFIER_POINTER (DECL_NAME (x))); return true; @@ -670,8 +682,11 @@ gfc_mark_addressable (tree exp) } #endif - pedwarn ("address of register variable %qs requested", - IDENTIFIER_POINTER (DECL_NAME (x))); + if (emit_diagnostics) + pedwarn ("address of register variable %qs requested", + IDENTIFIER_POINTER (DECL_NAME (x))); + if (!cancel_regdecl) + return false; } /* drops in */ @@ -683,6 +698,18 @@ gfc_mark_addressable (tree exp) } } +static bool +gfc_try_mark_addressable (tree exp, cancel_regdecl) +{ + return gfc_mark_addressable_internal (tree exp, cancel_regdecl, false); +} + +static bool +gfc_mark_addressable (tree exp) +{ + return gfc_mark_addressable_internal (tree exp, true, true); +} + /* press the big red button - garbage (ggc) collection is on */ int ggc_p = 1; Index: langhooks.h =================================================================== /usr/bin/diff -p -d -F^( -u -L langhooks.h (revision 110439) -L langhooks.h (working copy) .svn/text-base/langhooks.h.svn-base langhooks.h --- langhooks.h (revision 110439) +++ langhooks.h (working copy) @@ -328,6 +328,11 @@ struct lang_hooks compilation. Default hook is does nothing. */ void (*finish_incomplete_decl) (tree); + /* Try to mark EXP saying that we need to be able to take the address of + it; it should not be allocated in a register. Return true if + successful. */ + bool (*try_mark_addressable) (tree, bool); + /* Mark EXP saying that we need to be able to take the address of it; it should not be allocated in a register. Return true if successful. */ Index: c-typeck.c =================================================================== /usr/bin/diff -p -d -F^( -u -L c-typeck.c (revision 110439) -L c-typeck.c (working copy) .svn/text-base/c-typeck.c.svn-base c-typeck.c --- c-typeck.c (revision 110439) +++ c-typeck.c (working copy) @@ -3120,10 +3120,14 @@ lvalue_or_else (tree ref, enum lvalue_us /* Mark EXP saying that we need to be able to take the address of it; it should not be allocated in a register. - Returns true if successful. */ + Returns true if successful. + If CANCEL_REGDECL is set, ignore register declarations for local + variables / parameters unless a specific hard register was requested. + If EMIT_DIAGNOSTICS is set, emit errors / warnings. */ -bool -c_mark_addressable (tree exp) +static bool +c_mark_addressable_internal (tree exp, bool cancel_regdecl, + bool emit_diagnostics) { tree x = exp; @@ -3133,8 +3137,9 @@ c_mark_addressable (tree exp) case COMPONENT_REF: if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) { - error - ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1)); + if (emit_diagnostics) + error ("cannot take address of bit-field %qD", + TREE_OPERAND (x, 1)); return false; } @@ -3161,17 +3166,32 @@ c_mark_addressable (tree exp) { if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x)) { - error - ("global register variable %qD used in nested function", x); + if (emit_diagnostics) + error + ("global register variable %qD used in nested function", x); return false; } - pedwarn ("register variable %qD used in nested function", x); + if (emit_diagnostics) + pedwarn ("register variable %qD used in nested function", x); } else if (C_DECL_REGISTER (x)) { if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x)) - error ("address of global register variable %qD requested", x); - else + { + if (emit_diagnostics) + error ("address of global register variable %qD requested", + x); + } + else if (!DECL_REGISTER (x) + || (cancel_regdecl + && !(REG_P (DECL_RTL (x)) + && REGNO (DECL_RTL (x)) < FIRST_PSEUDO_REGISTER))) + { + DECL_REGISTER (x) = 0; + TREE_ADDRESSABLE (x) = 1; + return true; + } + else if (emit_diagnostics) error ("address of register variable %qD requested", x); return false; } @@ -3184,6 +3204,18 @@ c_mark_addressable (tree exp) return true; } } + +bool +c_try_mark_addressable (tree exp, bool cancel_regdecl) +{ + return c_mark_addressable_internal (exp, cancel_regdecl, false); +} + +bool +c_mark_addressable (tree exp) +{ + return c_mark_addressable_internal (exp, false, true); +} /* Build and return a conditional expression IFEXP ? OP1 : OP2. */ Index: treelang/treetree.c =================================================================== /usr/bin/diff -p -d -F^( -u -L treelang/treetree.c (revision 110439) -L treelang/treetree.c (working copy) treelang/.svn/text-base/treetree.c.svn-base treelang/treetree.c --- treelang/treetree.c (revision 110439) +++ treelang/treetree.c (working copy) @@ -124,6 +124,7 @@ struct language_function GTY(()) char junk; /* dummy field to ensure struct is not empty */ }; +static bool tree_try_mark_addressable (tree exp, bool); static bool tree_mark_addressable (tree exp); static tree tree_lang_type_for_size (unsigned precision, int unsignedp); static tree tree_lang_type_for_mode (enum machine_mode mode, int unsignedp); @@ -154,6 +155,8 @@ static void treelang_expand_function (tr end). These are not really very language-dependent, i.e. treelang, C, Mercury, etc. can all use almost the same definitions. */ +#undef LANG_HOOKS_TRY_MARK_ADDRESSABLE +#define LANG_HOOKS_TRY_MARK_ADDRESSABLE tree_try_mark_addressable #undef LANG_HOOKS_MARK_ADDRESSABLE #define LANG_HOOKS_MARK_ADDRESSABLE tree_mark_addressable #undef LANG_HOOKS_SIGNED_TYPE @@ -779,11 +782,14 @@ static GTY(()) tree signed_and_unsigned_ /* Mark EXP saying that we need to be able to take the address of it; it should not be allocated in a register. Value is 1 if successful. + If CANCEL_REGDECL is set, ignore register declarations for local + variables / parameters unless a specific hard register was requested. This implementation was copied from c-decl.c. */ static bool -tree_mark_addressable (tree exp) +tree_mark_addressable_internal (tree exp, bool cancel_regdecl, + bool emit_diagnostics) { register tree x = exp; while (1) @@ -810,22 +816,29 @@ tree_mark_addressable (tree exp) { if (TREE_PUBLIC (x)) { - error ("Global register variable %qD used in nested function.", - x); + if (emit_diagnostics) + error + ("Global register variable %qD used in nested function.", + x); return 0; } - pedwarn ("Register variable %qD used in nested function.", x); + if (emit_diagnostics) + pedwarn ("Register variable %qD used in nested function.", x); } else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)) { if (TREE_PUBLIC (x)) { - error ("Address of global register variable %qD requested.", - x); + if (emit_diagnostics) + error ("Address of global register variable %qD requested.", + x); return 0; } - pedwarn ("Address of register variable %qD requested.", x); + if (emit_diagnostics) + pedwarn ("Address of register variable %qD requested.", x); + if (!cancel_regdecls) + return false; } /* drops in */ @@ -837,6 +850,21 @@ tree_mark_addressable (tree exp) } } +/* Likewise, but don't provide option of emitting diagnostics. */ +static bool +tree_try_mark_addressable (tree exp, bool cancel_regdecl) +{ + return tree_mark_addressable_internal (exp, cancel_regdecl, false); +} + +/* Likewise, but always cancel register declarations unless they specify + a specific registyer, and always emit diagnostics. */ +static bool +tree_mark_addressable (tree exp) +{ + return tree_mark_addressable_internal (exp, true, true); +} + /* Return an integer type with the number of bits of precision given by PRECISION. UNSIGNEDP is nonzero if the type is unsigned; otherwise it is a signed type. */ Index: langhooks-def.h =================================================================== /usr/bin/diff -p -d -F^( -u -L langhooks-def.h (revision 110439) -L langhooks-def.h (working copy) .svn/text-base/langhooks-def.h.svn-base langhooks-def.h --- langhooks-def.h (revision 110439) +++ langhooks-def.h (working copy) @@ -296,6 +296,7 @@ extern tree lhd_make_node (enum tree_cod LANG_HOOKS_EXPAND_DECL, \ LANG_HOOKS_SAFE_FROM_P, \ LANG_HOOKS_FINISH_INCOMPLETE_DECL, \ + LANG_HOOKS_TRY_MARK_ADDRESSABLE, \ LANG_HOOKS_MARK_ADDRESSABLE, \ LANG_HOOKS_STATICP, \ LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \