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;
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)
#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) \
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.
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 ()
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))
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;
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,
&& 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
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
}
/* 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;
}
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;
{
block_scope = true;
DECL_CONTEXT (fndecl) = global_namespace;
+ DECL_LOCAL_DECL_P (fndecl) = true;
if (!processing_template_decl)
pushdecl (fndecl);
}
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. */
/* 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;
&& 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));
{
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);
}
fn = STRIP_TEMPLATE (fn);
if (!DECL_FUNCTION_MEMBER_P (fn)
- && !DECL_LOCAL_FUNCTION_P (fn))
+ && !DECL_LOCAL_DECL_P (fn))
koenig_p = true;
}
}