diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-09-10 05:38:29 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-09-10 05:45:46 -0700 |
commit | f40866967d69079fdde293feb32d2eb52cb93cc8 (patch) | |
tree | 606b4400706a8a4f96d751e05b3bad2356e67a88 /gcc/cp | |
parent | d41f8429e9e1b21d862c9a934b129739a3408c79 (diff) | |
download | gcc-f40866967d69079fdde293feb32d2eb52cb93cc8.zip gcc-f40866967d69079fdde293feb32d2eb52cb93cc8.tar.gz gcc-f40866967d69079fdde293feb32d2eb52cb93cc8.tar.bz2 |
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.
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 10 | ||||
-rw-r--r-- | gcc/cp/decl.c | 19 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 45 | ||||
-rw-r--r-- | gcc/cp/parser.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 |
7 files changed, 35 insertions, 51 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 61bbb38..5606389 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7873941..b12c787 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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) \ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ce97d19..be2bc9d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 3c2ddc1..bbeaf64 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0da3839..916ea6c 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4e21262..d4ece38 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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)); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 107d39d..dafb403 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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); } |