From 31ed8fea3d618377c79be11b05f41539df915cc4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 8 Oct 2001 09:37:06 -0700 Subject: [PATCH] c-common.h (struct c_lang_decl): Add declared_inline. * c-common.h (struct c_lang_decl): Add declared_inline. * c-tree.h (DECL_DECLARED_INLINE_P): New. * c-lang.c (c_disregard_inline_limits): Use it. * c-decl.c (duplicate_decls): Likewise. (pushdecl, redeclaration_error_message): Likewise. (pushdecl): Allocate DECL_LANG_SPECIFIC if needed. (grokdeclarator): Likewise. Set DECL_DECLARED_INLINE_P. Set DECL_INLINE if -finline-functions. (store_parm_decls): Don't allocate DECL_LANG_SPECIFIC here. * cp-tree.h (struct lang_decl_flags): Remove declared_inline. (DECL_DECLARED_INLINE_P): Use the bit in struct c_lang_decl. From-SVN: r46079 --- gcc/ChangeLog | 12 +++++++++++ gcc/c-common.h | 2 +- gcc/c-decl.c | 56 ++++++++++++++++++++++++++++++++++-------------- gcc/c-lang.c | 2 +- gcc/c-tree.h | 7 +++++- gcc/cp/ChangeLog | 5 +++++ gcc/cp/cp-tree.h | 7 +++--- 7 files changed, 68 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 559df72d18f..353151bb3a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2001-10-08 Richard Henderson + + * c-common.h (struct c_lang_decl): Add declared_inline. + * c-tree.h (DECL_DECLARED_INLINE_P): New. + * c-lang.c (c_disregard_inline_limits): Use it. + * c-decl.c (duplicate_decls): Likewise. + (pushdecl, redeclaration_error_message): Likewise. + (pushdecl): Allocate DECL_LANG_SPECIFIC if needed. + (grokdeclarator): Likewise. Set DECL_DECLARED_INLINE_P. + Set DECL_INLINE if -finline-functions. + (store_parm_decls): Don't allocate DECL_LANG_SPECIFIC here. + 2001-10-08 Neil Booth * cppmacro.c (funlike_invocation_p): Move some logic to caller diff --git a/gcc/c-common.h b/gcc/c-common.h index 2212ceea865..2d99513d724 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -338,7 +338,7 @@ extern void mark_stmt_tree PARAMS ((void *)); DECL_LANG_SPECIFIC field. */ struct c_lang_decl { - char dummy; + unsigned declared_inline : 1; }; /* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is diff --git a/gcc/c-decl.c b/gcc/c-decl.c index e35969464de..4ec34eace4d 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1727,12 +1727,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level) /* Warn if function is now inline but was previously declared not inline and has been called. */ if (TREE_CODE (olddecl) == FUNCTION_DECL - && ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl) + && ! DECL_DECLARED_INLINE_P (olddecl) + && DECL_DECLARED_INLINE_P (newdecl) && TREE_USED (olddecl)) warning_with_decl (newdecl, "`%s' declared inline after being called"); if (TREE_CODE (olddecl) == FUNCTION_DECL - && ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl) + && ! DECL_DECLARED_INLINE_P (olddecl) + && DECL_DECLARED_INLINE_P (newdecl) && DECL_INITIAL (olddecl) != 0) warning_with_decl (newdecl, "`%s' declared inline after its definition"); @@ -1976,10 +1978,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level) { /* If either decl says `inline', this fn is inline, unless its definition was passed already. */ - if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) - DECL_INLINE (olddecl) = 1; + if (DECL_DECLARED_INLINE_P (newdecl) + && DECL_DECLARED_INLINE_P (olddecl) == 0) + DECL_DECLARED_INLINE_P (olddecl) = 1; - DECL_INLINE (newdecl) = DECL_INLINE (olddecl); + DECL_DECLARED_INLINE_P (newdecl) = DECL_DECLARED_INLINE_P (olddecl); } if (DECL_BUILT_IN (olddecl)) @@ -2056,6 +2059,11 @@ pushdecl (x) register tree name = DECL_NAME (x); register struct binding_level *b = current_binding_level; + /* Functions need the lang_decl data. */ + if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x)) + DECL_LANG_SPECIFIC (x) = (struct lang_decl *) + ggc_alloc_cleared (sizeof (struct lang_decl)); + DECL_CONTEXT (x) = current_function_decl; /* A local extern declaration for a function doesn't constitute nesting. A local auto declaration does, since it's a forward decl @@ -2351,7 +2359,8 @@ pushdecl (x) && oldglobal != 0 && TREE_CODE (x) == FUNCTION_DECL && TREE_CODE (oldglobal) == FUNCTION_DECL - && DECL_EXTERNAL (x) && ! DECL_INLINE (x)) + && DECL_EXTERNAL (x) + && ! DECL_DECLARED_INLINE_P (x)) { /* We have one. Their types must agree. */ if (! comptypes (TREE_TYPE (x), @@ -2361,8 +2370,10 @@ pushdecl (x) { /* Inner extern decl is inline if global one is. Copy enough to really inline it. */ - if (DECL_INLINE (oldglobal)) + if (DECL_DECLARED_INLINE_P (oldglobal)) { + DECL_DECLARED_INLINE_P (x) + = DECL_DECLARED_INLINE_P (oldglobal); DECL_INLINE (x) = DECL_INLINE (oldglobal); DECL_INITIAL (x) = (current_function_decl == oldglobal ? 0 : DECL_INITIAL (oldglobal)); @@ -2613,8 +2624,9 @@ redeclaration_error_message (newdecl, olddecl) if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0 /* However, defining once as extern inline and a second time in another way is ok. */ - && ! (DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl) - && ! (DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl)))) + && ! (DECL_DECLARED_INLINE_P (olddecl) && DECL_EXTERNAL (olddecl) + && ! (DECL_DECLARED_INLINE_P (newdecl) + && DECL_EXTERNAL (newdecl)))) return 1; return 0; } @@ -4913,6 +4925,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) decl = build_decl (FUNCTION_DECL, declarator, type); decl = build_decl_attribute_variant (decl, decl_attr); + DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) + ggc_alloc_cleared (sizeof (struct lang_decl)); + if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl)) pedwarn ("ISO C forbids qualified function types"); @@ -4929,17 +4944,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO))); /* Record presence of `inline', if it is reasonable. */ - if (inlinep) + if (MAIN_NAME_P (declarator)) { - if (MAIN_NAME_P (declarator)) + if (inlinep) warning ("cannot inline function `main'"); - else - /* Assume that otherwise the function can be inlined. */ - DECL_INLINE (decl) = 1; + } + else if (inlinep) + { + /* Assume that otherwise the function can be inlined. */ + DECL_INLINE (decl) = 1; + DECL_DECLARED_INLINE_P (decl) = 1; if (specbits & (1 << (int) RID_EXTERN)) current_extern_inline = 1; } + /* If -finline-functions, assume it can be inlined. This does + two things: let the function be deferred until it is actually + needed, and let dwarf2 know that the function is inlinable. */ + else if (flag_inline_trees == 2) + { + DECL_INLINE (decl) = 1; + DECL_DECLARED_INLINE_P (decl) = 0; + } } else { @@ -6593,8 +6619,6 @@ store_parm_decls () init_function_start (fndecl, input_filename, lineno); /* Begin the statement tree for this function. */ - DECL_LANG_SPECIFIC (current_function_decl) - =((struct lang_decl *) ggc_alloc_cleared (sizeof (struct lang_decl))); begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl)); /* If this is a nested function, save away the sizes of any diff --git a/gcc/c-lang.c b/gcc/c-lang.c index 7e7ebb74eed..6ff8b9c72be 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -340,7 +340,7 @@ static int c_disregard_inline_limits (fn) tree fn; { - return DECL_INLINE (fn) && DECL_EXTERNAL (fn); + return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn); } static tree inline_forbidden_p PARAMS ((tree *, int *, void *)); diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 6f1833af414..6d0553902d4 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -98,9 +98,14 @@ struct lang_decl /* In an IDENTIFIER_NODE, nonzero if this identifier is actually a keyword. C_RID_CODE (node) is then the RID_* value of the keyword, and C_RID_YYCODE is the token number wanted by Yacc. */ - #define C_IS_RESERVED_WORD(id) TREE_LANG_FLAG_0 (id) +/* This function was declared inline. This flag controls the linkage + semantics of 'inline'; whether or not the function is inlined is + controlled by DECL_INLINE. */ +#define DECL_DECLARED_INLINE_P(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->base.declared_inline) + /* In a RECORD_TYPE, a sorted array of the fields of the type. */ struct lang_type { diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a7a008f8def..60e8151a0c6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2001-10-08 Richard Henderson + + * cp-tree.h (struct lang_decl_flags): Remove declared_inline. + (DECL_DECLARED_INLINE_P): Use the bit in struct c_lang_decl. + 2001-10-07 Kaveh R. Ghazi * class.c (build_vtable_entry_ref): Const-ify. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 98e747da6ff..03769942716 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1705,17 +1705,16 @@ struct lang_decl_flags unsigned deferred : 1; unsigned use_template : 2; unsigned nonconverting : 1; - unsigned declared_inline : 1; unsigned not_really_extern : 1; unsigned needs_final_overrider : 1; unsigned initialized_in_class : 1; - unsigned pending_inline_p : 1; + unsigned global_ctor_p : 1; unsigned global_dtor_p : 1; unsigned assignment_operator_p : 1; unsigned anticipated_p : 1; - /* Three unused bits. */ + /* Four unused bits. */ union { /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this @@ -2838,7 +2837,7 @@ enum ptrmemfunc_vbit_where_t semantics of 'inline'; whether or not the function is inlined is controlled by DECL_INLINE. */ #define DECL_DECLARED_INLINE_P(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->decl_flags.declared_inline) + (DECL_LANG_SPECIFIC (NODE)->decl_flags.base.declared_inline) /* DECL_EXTERNAL must be set on a decl until the decl is actually emitted, so that assemble_external will work properly. So we have this flag to