summaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c107
1 files changed, 67 insertions, 40 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 150e8662a5e..ea1a08d2674 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3296,7 +3296,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
error ("%qD used without template parameters", name);
return error_mark_node;
}
- gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+ gcc_assert (identifier_p (name));
gcc_assert (TYPE_P (context));
if (!MAYBE_CLASS_TYPE_P (context))
@@ -3402,7 +3402,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
name = TYPE_IDENTIFIER (name);
else if (DECL_P (name))
name = DECL_NAME (name);
- gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+ gcc_assert (identifier_p (name));
if (!dependent_type_p (context)
|| currently_open_class (context))
@@ -4781,7 +4781,7 @@ check_array_designated_initializer (const constructor_elt *ce,
}
else
{
- gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
+ gcc_assert (identifier_p (ce->index));
error ("name %qD used in a GNU-style designated "
"initializer for an array", ce->index);
}
@@ -6434,11 +6434,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
/* Check for abstractness of the type. Notice that there is no
need to strip array types here since the check for those types
is already done within create_array_type_for_decl. */
- if (TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE)
- abstract_virtuals_error (decl, TREE_TYPE (type));
- else
- abstract_virtuals_error (decl, type);
+ abstract_virtuals_error (decl, type);
if (TREE_TYPE (decl) == error_mark_node)
/* No initialization required. */
@@ -6758,10 +6754,9 @@ register_dtor_fn (tree decl)
"__aeabi_atexit"), and DECL is a class object, we can just pass the
destructor to "__cxa_atexit"; we don't have to build a temporary
function to do the cleanup. */
- ob_parm = (DECL_THREAD_LOCAL_P (decl)
- || (flag_use_cxa_atexit
- && !targetm.cxx.use_atexit_for_cxa_atexit ()));
- dso_parm = ob_parm;
+ dso_parm = (flag_use_cxa_atexit
+ && !targetm.cxx.use_atexit_for_cxa_atexit ());
+ ob_parm = (DECL_THREAD_LOCAL_P (decl) || dso_parm);
use_dtor = ob_parm && CLASS_TYPE_P (type);
if (use_dtor)
{
@@ -6825,7 +6820,7 @@ register_dtor_fn (tree decl)
before passing it in, to avoid spurious errors. */
addr = build_nop (ptr_type_node, addr);
}
- else if (ob_parm)
+ else
/* Since the cleanup functions we build ignore the address
they're given, there's no reason to pass the actual address
in, and, in general, it's cheaper to pass NULL than any
@@ -6835,6 +6830,10 @@ register_dtor_fn (tree decl)
if (dso_parm)
arg2 = cp_build_addr_expr (get_dso_handle_node (),
tf_warning_or_error);
+ else if (ob_parm)
+ /* Just pass NULL to the dso handle parm if we don't actually
+ have a DSO handle on this target. */
+ arg2 = null_pointer_node;
else
arg2 = NULL_TREE;
@@ -7414,8 +7413,7 @@ grokfndecl (tree ctype,
== current_class_type);
fns = TREE_OPERAND (fns, 1);
}
- gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE
- || TREE_CODE (fns) == OVERLOAD);
+ gcc_assert (identifier_p (fns) || TREE_CODE (fns) == OVERLOAD);
DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args);
for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
@@ -7773,7 +7771,7 @@ grokvardecl (tree type,
tree decl;
tree explicit_scope;
- gcc_assert (!name || TREE_CODE (name) == IDENTIFIER_NODE);
+ gcc_assert (!name || identifier_p (name));
/* Compute the scope in which to place the variable, but remember
whether or not that scope was explicitly specified by the user. */
@@ -8510,7 +8508,7 @@ check_var_type (tree identifier, tree type)
{
if (!identifier)
error ("unnamed variable or field declared void");
- else if (TREE_CODE (identifier) == IDENTIFIER_NODE)
+ else if (identifier_p (identifier))
{
gcc_assert (!IDENTIFIER_OPNAME_P (identifier));
error ("variable or field %qE declared void", identifier);
@@ -8653,6 +8651,7 @@ grokdeclarator (const cp_declarator *declarator,
bool template_type_arg = false;
bool template_parm_flag = false;
bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
+ source_location saved_loc = input_location;
const char *errmsg;
signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
@@ -8778,7 +8777,7 @@ grokdeclarator (const cp_declarator *declarator,
tree fns = TREE_OPERAND (decl, 0);
dname = fns;
- if (TREE_CODE (dname) != IDENTIFIER_NODE)
+ if (!identifier_p (dname))
{
gcc_assert (is_overloaded_fn (dname));
dname = DECL_NAME (get_first_fn (dname));
@@ -8787,7 +8786,7 @@ grokdeclarator (const cp_declarator *declarator,
/* Fall through. */
case IDENTIFIER_NODE:
- if (TREE_CODE (decl) == IDENTIFIER_NODE)
+ if (identifier_p (decl))
dname = decl;
if (C_IS_RESERVED_WORD (dname))
@@ -8852,7 +8851,7 @@ grokdeclarator (const cp_declarator *declarator,
}
if (dname
- && TREE_CODE (dname) == IDENTIFIER_NODE
+ && identifier_p (dname)
&& UDLIT_OPER_P (dname)
&& innermost_code != cdk_function)
{
@@ -8977,7 +8976,7 @@ grokdeclarator (const cp_declarator *declarator,
common. With no options, it is allowed. With -Wreturn-type,
it is a warning. It is only an error with -pedantic-errors. */
is_main = (funcdef_flag
- && dname && TREE_CODE (dname) == IDENTIFIER_NODE
+ && dname && identifier_p (dname)
&& MAIN_NAME_P (dname)
&& ctype == NULL_TREE
&& in_namespace == NULL_TREE
@@ -9337,7 +9336,6 @@ grokdeclarator (const cp_declarator *declarator,
if (declspecs->std_attributes)
{
/* Apply the c++11 attributes to the type preceding them. */
- source_location saved_loc = input_location;
input_location = declspecs->locations[ds_std_attribute];
decl_attributes (&type, declspecs->std_attributes, 0);
input_location = saved_loc;
@@ -9425,11 +9423,10 @@ grokdeclarator (const cp_declarator *declarator,
error ("%qs declared as function returning an array", name);
return error_mark_node;
}
- /* When decl_context == NORMAL we emit a better error message
- later in abstract_virtuals_error. */
- if (decl_context == TYPENAME && ABSTRACT_CLASS_TYPE_P (type))
- error ("%qs declared as function returning an abstract "
- "class type", name);
+
+ input_location = declspecs->locations[ds_type_spec];
+ abstract_virtuals_error (ACU_RETURN, type);
+ input_location = saved_loc;
/* Pick up type qualifiers which should be applied to `this'. */
memfn_quals = declarator->u.function.qualifiers;
@@ -9632,9 +9629,11 @@ grokdeclarator (const cp_declarator *declarator,
but to the target of the pointer. */
type_quals = TYPE_UNQUALIFIED;
+ /* This code used to handle METHOD_TYPE, but I don't think it's
+ possible to get it here anymore. */
+ gcc_assert (TREE_CODE (type) != METHOD_TYPE);
if (declarator->kind == cdk_ptrmem
- && (TREE_CODE (type) == FUNCTION_TYPE
- || (memfn_quals && TREE_CODE (type) == METHOD_TYPE)))
+ && TREE_CODE (type) == FUNCTION_TYPE)
{
memfn_quals |= type_memfn_quals (type);
type = build_memfn_type (type,
@@ -10800,9 +10799,8 @@ static tree
local_variable_p_walkfn (tree *tp, int *walk_subtrees,
void * /*data*/)
{
- /* Check DECL_NAME to avoid including temporaries. We don't check
- DECL_ARTIFICIAL because we do want to complain about 'this'. */
- if (local_variable_p (*tp) && DECL_NAME (*tp))
+ if (local_variable_p (*tp)
+ && (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier))
return *tp;
else if (TYPE_P (*tp))
*walk_subtrees = 0;
@@ -11890,13 +11888,14 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
static tree
xref_tag_1 (enum tag_types tag_code, tree name,
- tag_scope scope, bool template_header_p)
+ tag_scope orig_scope, bool template_header_p)
{
enum tree_code code;
tree t;
tree context = NULL_TREE;
+ tag_scope scope;
- gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+ gcc_assert (identifier_p (name));
switch (tag_code)
{
@@ -11914,6 +11913,11 @@ xref_tag_1 (enum tag_types tag_code, tree name,
gcc_unreachable ();
}
+ if (orig_scope == ts_lambda)
+ scope = ts_current;
+ else
+ scope = orig_scope;
+
/* In case of anonymous name, xref_tag is only called to
make type node and push name. Name lookup is not required. */
if (ANON_AGGRNAME_P (name))
@@ -11987,6 +11991,10 @@ xref_tag_1 (enum tag_types tag_code, tree name,
{
t = make_class_type (code);
TYPE_CONTEXT (t) = context;
+ if (orig_scope == ts_lambda)
+ /* Remember that we're declaring a lambda to avoid bogus errors
+ in push_template_decl. */
+ CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
t = pushtag (name, t, scope);
}
}
@@ -12314,7 +12322,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
bool scoped_enum_p, bool *is_new)
{
tree prevtype = NULL_TREE;
- gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+ gcc_assert (identifier_p (name));
if (is_new)
*is_new = false;
@@ -14009,7 +14017,10 @@ grokmethod (cp_decl_specifier_seq *declspecs,
/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that
- we can lay it out later, when and if its type becomes complete. */
+ we can lay it out later, when and if its type becomes complete.
+
+ Also handle constexpr pointer to member variables where the initializer
+ is an unlowered PTRMEM_CST because the class isn't complete yet. */
void
maybe_register_incomplete_var (tree var)
@@ -14034,6 +14045,15 @@ maybe_register_incomplete_var (tree var)
incomplete_var iv = {var, inner_type};
vec_safe_push (incomplete_vars, iv);
}
+ else if (TYPE_PTRMEM_P (inner_type)
+ && DECL_INITIAL (var)
+ && TREE_CODE (DECL_INITIAL (var)) == PTRMEM_CST)
+ {
+ tree context = TYPE_PTRMEM_CLASS_TYPE (inner_type);
+ gcc_assert (TYPE_BEING_DEFINED (context));
+ incomplete_var iv = {var, context};
+ vec_safe_push (incomplete_vars, iv);
+ }
}
}
@@ -14053,10 +14073,17 @@ complete_vars (tree type)
{
tree var = iv->decl;
tree type = TREE_TYPE (var);
- /* Complete the type of the variable. The VAR_DECL itself
- will be laid out in expand_expr. */
- complete_type (type);
- cp_apply_type_quals_to_decl (cp_type_quals (type), var);
+
+ if (TYPE_PTRMEM_P (type))
+ DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
+ else
+ {
+ /* Complete the type of the variable. The VAR_DECL itself
+ will be laid out in expand_expr. */
+ complete_type (type);
+ cp_apply_type_quals_to_decl (cp_type_quals (type), var);
+ }
+
/* Remove this entry from the list. */
incomplete_vars->unordered_remove (ix);
}