Commit 31ed8fea by Richard Henderson Committed by Richard Henderson

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
parent bbd300a9
2001-10-08 Richard Henderson <rth@redhat.com>
* 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 <neil@daikokuya.demon.co.uk> 2001-10-08 Neil Booth <neil@daikokuya.demon.co.uk>
* cppmacro.c (funlike_invocation_p): Move some logic to caller * cppmacro.c (funlike_invocation_p): Move some logic to caller
......
...@@ -338,7 +338,7 @@ extern void mark_stmt_tree PARAMS ((void *)); ...@@ -338,7 +338,7 @@ extern void mark_stmt_tree PARAMS ((void *));
DECL_LANG_SPECIFIC field. */ DECL_LANG_SPECIFIC field. */
struct c_lang_decl { struct c_lang_decl {
char dummy; unsigned declared_inline : 1;
}; };
/* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is /* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is
......
...@@ -1727,12 +1727,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level) ...@@ -1727,12 +1727,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
/* Warn if function is now inline /* Warn if function is now inline
but was previously declared not inline and has been called. */ but was previously declared not inline and has been called. */
if (TREE_CODE (olddecl) == FUNCTION_DECL 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)) && TREE_USED (olddecl))
warning_with_decl (newdecl, warning_with_decl (newdecl,
"`%s' declared inline after being called"); "`%s' declared inline after being called");
if (TREE_CODE (olddecl) == FUNCTION_DECL 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) && DECL_INITIAL (olddecl) != 0)
warning_with_decl (newdecl, warning_with_decl (newdecl,
"`%s' declared inline after its definition"); "`%s' declared inline after its definition");
...@@ -1976,10 +1978,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level) ...@@ -1976,10 +1978,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
{ {
/* If either decl says `inline', this fn is inline, /* If either decl says `inline', this fn is inline,
unless its definition was passed already. */ unless its definition was passed already. */
if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) if (DECL_DECLARED_INLINE_P (newdecl)
DECL_INLINE (olddecl) = 1; && 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)) if (DECL_BUILT_IN (olddecl))
...@@ -2056,6 +2059,11 @@ pushdecl (x) ...@@ -2056,6 +2059,11 @@ pushdecl (x)
register tree name = DECL_NAME (x); register tree name = DECL_NAME (x);
register struct binding_level *b = current_binding_level; 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; DECL_CONTEXT (x) = current_function_decl;
/* A local extern declaration for a function doesn't constitute nesting. /* A local extern declaration for a function doesn't constitute nesting.
A local auto declaration does, since it's a forward decl A local auto declaration does, since it's a forward decl
...@@ -2351,7 +2359,8 @@ pushdecl (x) ...@@ -2351,7 +2359,8 @@ pushdecl (x)
&& oldglobal != 0 && oldglobal != 0
&& TREE_CODE (x) == FUNCTION_DECL && TREE_CODE (x) == FUNCTION_DECL
&& TREE_CODE (oldglobal) == 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. */ /* We have one. Their types must agree. */
if (! comptypes (TREE_TYPE (x), if (! comptypes (TREE_TYPE (x),
...@@ -2361,8 +2370,10 @@ pushdecl (x) ...@@ -2361,8 +2370,10 @@ pushdecl (x)
{ {
/* Inner extern decl is inline if global one is. /* Inner extern decl is inline if global one is.
Copy enough to really inline it. */ 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_INLINE (x) = DECL_INLINE (oldglobal);
DECL_INITIAL (x) = (current_function_decl == oldglobal DECL_INITIAL (x) = (current_function_decl == oldglobal
? 0 : DECL_INITIAL (oldglobal)); ? 0 : DECL_INITIAL (oldglobal));
...@@ -2613,8 +2624,9 @@ redeclaration_error_message (newdecl, olddecl) ...@@ -2613,8 +2624,9 @@ redeclaration_error_message (newdecl, olddecl)
if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0 if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
/* However, defining once as extern inline and a second /* However, defining once as extern inline and a second
time in another way is ok. */ time in another way is ok. */
&& ! (DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl) && ! (DECL_DECLARED_INLINE_P (olddecl) && DECL_EXTERNAL (olddecl)
&& ! (DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl)))) && ! (DECL_DECLARED_INLINE_P (newdecl)
&& DECL_EXTERNAL (newdecl))))
return 1; return 1;
return 0; return 0;
} }
...@@ -4913,6 +4925,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) ...@@ -4913,6 +4925,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
decl = build_decl (FUNCTION_DECL, declarator, type); decl = build_decl (FUNCTION_DECL, declarator, type);
decl = build_decl_attribute_variant (decl, decl_attr); 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)) if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ISO C forbids qualified function types"); pedwarn ("ISO C forbids qualified function types");
...@@ -4929,17 +4944,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) ...@@ -4929,17 +4944,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
= !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO))); = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
/* Record presence of `inline', if it is reasonable. */ /* 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'"); warning ("cannot inline function `main'");
else }
/* Assume that otherwise the function can be inlined. */ else if (inlinep)
DECL_INLINE (decl) = 1; {
/* Assume that otherwise the function can be inlined. */
DECL_INLINE (decl) = 1;
DECL_DECLARED_INLINE_P (decl) = 1;
if (specbits & (1 << (int) RID_EXTERN)) if (specbits & (1 << (int) RID_EXTERN))
current_extern_inline = 1; 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 else
{ {
...@@ -6593,8 +6619,6 @@ store_parm_decls () ...@@ -6593,8 +6619,6 @@ store_parm_decls ()
init_function_start (fndecl, input_filename, lineno); init_function_start (fndecl, input_filename, lineno);
/* Begin the statement tree for this function. */ /* 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)); begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl));
/* If this is a nested function, save away the sizes of any /* If this is a nested function, save away the sizes of any
......
...@@ -340,7 +340,7 @@ static int ...@@ -340,7 +340,7 @@ static int
c_disregard_inline_limits (fn) c_disregard_inline_limits (fn)
tree 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 *)); static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
......
...@@ -98,9 +98,14 @@ struct lang_decl ...@@ -98,9 +98,14 @@ struct lang_decl
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a /* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
keyword. C_RID_CODE (node) is then the RID_* value of the keyword, keyword. C_RID_CODE (node) is then the RID_* value of the keyword,
and C_RID_YYCODE is the token number wanted by Yacc. */ and C_RID_YYCODE is the token number wanted by Yacc. */
#define C_IS_RESERVED_WORD(id) TREE_LANG_FLAG_0 (id) #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. */ /* In a RECORD_TYPE, a sorted array of the fields of the type. */
struct lang_type struct lang_type
{ {
......
2001-10-08 Richard Henderson <rth@redhat.com>
* 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 <ghazi@caip.rutgers.edu> 2001-10-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* class.c (build_vtable_entry_ref): Const-ify. * class.c (build_vtable_entry_ref): Const-ify.
......
...@@ -1705,17 +1705,16 @@ struct lang_decl_flags ...@@ -1705,17 +1705,16 @@ struct lang_decl_flags
unsigned deferred : 1; unsigned deferred : 1;
unsigned use_template : 2; unsigned use_template : 2;
unsigned nonconverting : 1; unsigned nonconverting : 1;
unsigned declared_inline : 1;
unsigned not_really_extern : 1; unsigned not_really_extern : 1;
unsigned needs_final_overrider : 1; unsigned needs_final_overrider : 1;
unsigned initialized_in_class : 1; unsigned initialized_in_class : 1;
unsigned pending_inline_p : 1; unsigned pending_inline_p : 1;
unsigned global_ctor_p : 1; unsigned global_ctor_p : 1;
unsigned global_dtor_p : 1; unsigned global_dtor_p : 1;
unsigned assignment_operator_p : 1; unsigned assignment_operator_p : 1;
unsigned anticipated_p : 1; unsigned anticipated_p : 1;
/* Three unused bits. */ /* Four unused bits. */
union { union {
/* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
...@@ -2838,7 +2837,7 @@ enum ptrmemfunc_vbit_where_t ...@@ -2838,7 +2837,7 @@ enum ptrmemfunc_vbit_where_t
semantics of 'inline'; whether or not the function is inlined is semantics of 'inline'; whether or not the function is inlined is
controlled by DECL_INLINE. */ controlled by DECL_INLINE. */
#define DECL_DECLARED_INLINE_P(NODE) \ #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, /* 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 so that assemble_external will work properly. So we have this flag to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment