c++: DECL_LOCAL_FUNCTION_P -> DECL_LOCAL_DECL_P
Our handling of block-scope extern decls is insufficient for modern C++, in particular modules, (but also constexprs). We mark such local function decls, and this patch extends that to marking local var decls too, so mainly a macro rename. Also, we set this flag earlier, rather than learning about it when pushing the decl. This is a step towards handling these properly. gcc/cp/ * cp-tree.h (DECL_LOCAL_FUNCTION_P): Rename to ... (DECL_LOCAL_DECL_P): ... here. Accept both fns and vars. * decl.c (start_decl): Set DECL_LOCAL_DECL_P for local externs. (omp_declare_variant_finalize_one): Use DECL_LOCAL_DECL_P. (local_variable_p): Simplify. * name-lookup.c (set_decl_context_in_fn): Assert DECL_LOCAL_DECL_P is as expected. Simplify. (do_pushdecl): Don't set decl_context_in_fn for friends. (is_local_extern): Simplify. * call.c (equal_functions): Use DECL_LOCAL_DECL_P. * parser.c (cp_parser_postfix_expression): Likewise. (cp_parser_omp_declare_reduction): Likewise. * pt.c (check_default_tmpl_args): Likewise. (tsubst_expr): Assert nested reduction function is local. (type_dependent_expression_p): Use DECL_LOCAL_DECL_P. * semantics.c (finish_call_expr): Likewise. libcc1/ * libcp1plugin.cc (plugin_build_call_expr): Use DECL_LOCAL_DECL_P.
This commit is contained in:
parent
d41f8429e9
commit
f40866967d
8 changed files with 36 additions and 52 deletions
|
@ -3631,7 +3631,7 @@ equal_functions (tree fn1, tree fn2)
|
|||
return 0;
|
||||
if (TREE_CODE (fn1) == TEMPLATE_DECL)
|
||||
return fn1 == fn2;
|
||||
if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
|
||||
if (DECL_LOCAL_DECL_P (fn1) || DECL_LOCAL_DECL_P (fn2)
|
||||
|| DECL_EXTERN_C_FUNCTION_P (fn1))
|
||||
return decls_match (fn1, fn2);
|
||||
return fn1 == fn2;
|
||||
|
|
|
@ -506,7 +506,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
|
|||
|
||||
Usage of DECL_LANG_FLAG_?:
|
||||
0: DECL_TEMPLATE_PARM_P (in PARM_DECL, CONST_DECL, TYPE_DECL, or TEMPLATE_DECL)
|
||||
DECL_LOCAL_FUNCTION_P (in FUNCTION_DECL)
|
||||
DECL_LOCAL_DECL_P (in FUNCTION_DECL, VAR_DECL)
|
||||
DECL_MUTABLE_P (in FIELD_DECL)
|
||||
DECL_DEPENDENT_P (in USING_DECL)
|
||||
LABEL_DECL_BREAK (in LABEL_DECL)
|
||||
|
@ -4009,10 +4009,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
#define TYPE_CONTAINS_VPTR_P(NODE) \
|
||||
(TYPE_POLYMORPHIC_P (NODE) || CLASSTYPE_VBASECLASSES (NODE))
|
||||
|
||||
/* Nonzero if NODE is a FUNCTION_DECL (for a function with global
|
||||
scope) declared in a local scope. */
|
||||
#define DECL_LOCAL_FUNCTION_P(NODE) \
|
||||
DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE))
|
||||
/* Nonzero if NODE is a FUNCTION_DECL or VARIABLE_DECL (for a decl
|
||||
with namespace scope) declared in a local scope. */
|
||||
#define DECL_LOCAL_DECL_P(NODE) \
|
||||
DECL_LANG_FLAG_0 (VAR_OR_FUNCTION_DECL_CHECK (NODE))
|
||||
|
||||
/* Nonzero if NODE is the target for genericization of 'break' stmts. */
|
||||
#define LABEL_DECL_BREAK(NODE) \
|
||||
|
|
|
@ -5199,8 +5199,8 @@ groktypename (cp_decl_specifier_seq *type_specifiers,
|
|||
return type;
|
||||
}
|
||||
|
||||
/* Process a DECLARATOR for a function-scope variable declaration,
|
||||
namespace-scope variable declaration, or function declaration.
|
||||
/* Process a DECLARATOR for a function-scope or namespace-scope
|
||||
variable or function declaration.
|
||||
(Function definitions go through start_function; class member
|
||||
declarations appearing in the body of the class go through
|
||||
grokfield.) The DECL corresponding to the DECLARATOR is returned.
|
||||
|
@ -5410,6 +5410,11 @@ start_decl (const cp_declarator *declarator,
|
|||
|
||||
was_public = TREE_PUBLIC (decl);
|
||||
|
||||
if ((DECL_EXTERNAL (decl) || TREE_CODE (decl) == FUNCTION_DECL)
|
||||
&& current_function_decl)
|
||||
/* A function-scope decl of some namespace-scope decl. */
|
||||
DECL_LOCAL_DECL_P (decl) = true;
|
||||
|
||||
/* Enter this declaration into the symbol table. Don't push the plain
|
||||
VAR_DECL for a variable template. */
|
||||
if (!template_parm_scope_p ()
|
||||
|
@ -7360,7 +7365,7 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
|
|||
fn = STRIP_TEMPLATE (fn);
|
||||
if (!((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn))
|
||||
|| DECL_FUNCTION_MEMBER_P (fn)
|
||||
|| DECL_LOCAL_FUNCTION_P (fn)))
|
||||
|| DECL_LOCAL_DECL_P (fn)))
|
||||
{
|
||||
koenig_p = true;
|
||||
if (!any_type_dependent_arguments_p (args))
|
||||
|
@ -13877,11 +13882,9 @@ int
|
|||
local_variable_p (const_tree t)
|
||||
{
|
||||
if ((VAR_P (t)
|
||||
/* A VAR_DECL with a context that is a _TYPE is a static data
|
||||
member. */
|
||||
&& !TYPE_P (CP_DECL_CONTEXT (t))
|
||||
/* Any other non-local variable must be at namespace scope. */
|
||||
&& !DECL_NAMESPACE_SCOPE_P (t))
|
||||
&& (DECL_LOCAL_DECL_P (t)
|
||||
|| !DECL_CONTEXT (t)
|
||||
|| TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL))
|
||||
|| (TREE_CODE (t) == PARM_DECL))
|
||||
return 1;
|
||||
|
||||
|
|
|
@ -2855,14 +2855,13 @@ check_local_shadow (tree decl)
|
|||
static void
|
||||
set_decl_context_in_fn (tree ctx, tree decl)
|
||||
{
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| (VAR_P (decl) && DECL_EXTERNAL (decl)))
|
||||
/* Make sure local externs are marked as such. */
|
||||
gcc_checking_assert (DECL_LOCAL_DECL_P (decl)
|
||||
&& DECL_NAMESPACE_SCOPE_P (decl));
|
||||
|
||||
if (!DECL_CONTEXT (decl)
|
||||
/* A local declaration for a function doesn't constitute
|
||||
nesting. */
|
||||
&& TREE_CODE (decl) != FUNCTION_DECL
|
||||
/* A local declaration for an `extern' variable is in the
|
||||
scope of the current namespace, not the current
|
||||
function. */
|
||||
&& !(VAR_P (decl) && DECL_EXTERNAL (decl))
|
||||
/* When parsing the parameter list of a function declarator,
|
||||
don't set DECL_CONTEXT to an enclosing function. When we
|
||||
push the PARM_DECLs in order to process the function body,
|
||||
|
@ -2871,12 +2870,6 @@ set_decl_context_in_fn (tree ctx, tree decl)
|
|||
&& current_binding_level->kind == sk_function_parms
|
||||
&& current_binding_level->this_entity == NULL))
|
||||
DECL_CONTEXT (decl) = ctx;
|
||||
|
||||
/* If this is the declaration for a namespace-scope function,
|
||||
but the declaration itself is in a local scope, mark the
|
||||
declaration. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (decl))
|
||||
DECL_LOCAL_FUNCTION_P (decl) = 1;
|
||||
}
|
||||
|
||||
/* DECL is a local-scope decl with linkage. SHADOWED is true if the
|
||||
|
@ -2998,7 +2991,7 @@ do_pushdecl (tree decl, bool is_friend)
|
|||
if (decl == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl)
|
||||
if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl && !is_friend)
|
||||
set_decl_context_in_fn (current_function_decl, decl);
|
||||
|
||||
/* The binding level we will be pushing into. During local class
|
||||
|
@ -6682,29 +6675,15 @@ lookup_type_scope (tree name, tag_scope scope)
|
|||
}
|
||||
|
||||
/* Returns true iff DECL is a block-scope extern declaration of a function
|
||||
or variable. */
|
||||
or variable. We will already have determined validity of the decl
|
||||
when pushing it. So we do not have to redo that lookup. */
|
||||
|
||||
bool
|
||||
is_local_extern (tree decl)
|
||||
{
|
||||
cxx_binding *binding;
|
||||
|
||||
/* For functions, this is easy. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
return DECL_LOCAL_FUNCTION_P (decl);
|
||||
|
||||
if (!VAR_P (decl))
|
||||
return false;
|
||||
if (!current_function_decl)
|
||||
return false;
|
||||
|
||||
/* For variables, this is not easy. We need to look at the binding stack
|
||||
for the identifier to see whether the decl we have is a local. */
|
||||
for (binding = IDENTIFIER_BINDING (DECL_NAME (decl));
|
||||
binding && binding->scope->kind != sk_namespace;
|
||||
binding = binding->previous)
|
||||
if (binding->value == decl)
|
||||
return LOCAL_BINDING_P (binding);
|
||||
if ((TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| TREE_CODE (decl) == VAR_DECL))
|
||||
return DECL_LOCAL_DECL_P (decl);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -7467,7 +7467,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
|||
if ((TREE_CODE (fn) == USING_DECL
|
||||
&& DECL_DEPENDENT_P (fn))
|
||||
|| DECL_FUNCTION_MEMBER_P (fn)
|
||||
|| DECL_LOCAL_FUNCTION_P (fn))
|
||||
|| DECL_LOCAL_DECL_P (fn))
|
||||
{
|
||||
do_adl_p = false;
|
||||
break;
|
||||
|
@ -42582,6 +42582,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
|
|||
{
|
||||
block_scope = true;
|
||||
DECL_CONTEXT (fndecl) = global_namespace;
|
||||
DECL_LOCAL_DECL_P (fndecl) = true;
|
||||
if (!processing_template_decl)
|
||||
pushdecl (fndecl);
|
||||
}
|
||||
|
|
|
@ -5417,7 +5417,7 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
|
|||
class template. */
|
||||
|
||||
if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (decl)))
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL && DECL_LOCAL_DECL_P (decl)))
|
||||
/* You can't have a function template declaration in a local
|
||||
scope, nor you can you define a member of a class template in a
|
||||
local scope. */
|
||||
|
@ -18080,6 +18080,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
|
|||
/* We pretend this is regular local extern decl of
|
||||
a namespace-scope fn. Then we make it really
|
||||
local, it is a nested function. */
|
||||
gcc_checking_assert (DECL_LOCAL_DECL_P (decl));
|
||||
DECL_CONTEXT (decl) = global_namespace;
|
||||
pushdecl (decl);
|
||||
DECL_CONTEXT (decl) = current_function_decl;
|
||||
|
@ -26978,7 +26979,7 @@ type_dependent_expression_p (tree expression)
|
|||
&& DECL_FRIEND_P (expression)
|
||||
&& (!DECL_FRIEND_CONTEXT (expression)
|
||||
|| dependent_type_p (DECL_FRIEND_CONTEXT (expression))))
|
||||
&& !DECL_LOCAL_FUNCTION_P (expression))
|
||||
&& !DECL_LOCAL_DECL_P (expression))
|
||||
{
|
||||
gcc_assert (!dependent_type_p (TREE_TYPE (expression))
|
||||
|| undeduced_auto_decl (expression));
|
||||
|
|
|
@ -2518,7 +2518,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
|
|||
{
|
||||
tree ifn = get_first_fn (fn);
|
||||
if (TREE_CODE (ifn) == FUNCTION_DECL
|
||||
&& DECL_LOCAL_FUNCTION_P (ifn))
|
||||
&& DECL_LOCAL_DECL_P (ifn))
|
||||
orig_fn = DECL_NAME (ifn);
|
||||
}
|
||||
|
||||
|
|
|
@ -3294,7 +3294,7 @@ plugin_build_call_expr (cc1_plugin::connection *self,
|
|||
fn = STRIP_TEMPLATE (fn);
|
||||
|
||||
if (!DECL_FUNCTION_MEMBER_P (fn)
|
||||
&& !DECL_LOCAL_FUNCTION_P (fn))
|
||||
&& !DECL_LOCAL_DECL_P (fn))
|
||||
koenig_p = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue