#include "cgraph.h"
#include "tree-iterator.h"
#include "vec.h"
+#include "target.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
if (deferred_access_no_check)
return;
- my_friendly_assert (TREE_CODE (binfo) == TREE_VEC, 20030623);
+ gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
ptr = VEC_last (deferred_access, deferred_access_stack);
expr = check_return_expr (expr);
if (!processing_template_decl)
{
- if (DECL_DESTRUCTOR_P (current_function_decl))
+ if (DECL_DESTRUCTOR_P (current_function_decl)
+ || (DECL_CONSTRUCTOR_P (current_function_decl)
+ && targetm.cxx.cdtor_returns_this ()))
{
/* Similarly, all destructors must run destructors for
base-classes before returning. So, all returns in a
destructor get sent to the DTOR_LABEL; finish_function emits
code to return a value there. */
- return finish_goto_stmt (dtor_label);
+ return finish_goto_stmt (cdtor_label);
}
}
processing templates. */
if (processing_template_decl)
{
- r = build (BIND_EXPR, NULL, NULL, r, NULL);
+ r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
TREE_SIDE_EFFECTS (r) = 1;
{
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr))))
/* This inhibits warnings in c_common_truthvalue_conversion. */
- C_SET_EXP_ORIGINAL_CODE (expr, ERROR_MARK);
+ TREE_NO_WARNING (expr) = 1;
if (TREE_CODE (expr) == OFFSET_REF)
/* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be
tree
finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
{
- my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909);
+ gcc_assert (TREE_CODE (decl) == FIELD_DECL);
if (!object)
{
{
tree scope;
tree qualifying_type = NULL_TREE;
+
+ /* If we're not checking, return imediately. */
+ if (deferred_access_no_check)
+ return;
/* Determine the SCOPE of DECL. */
scope = context_for_name_lookup (decl);
its bases. */
qualifying_type = currently_open_derived_class (scope);
- if (qualifying_type)
+ if (qualifying_type && IS_AGGR_TYPE_CODE (TREE_CODE (qualifying_type)))
+ /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
+ or similar in a default argument value. */
perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
}
expr = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (type), LOOKUP_NORMAL);
+ type, LOOKUP_NORMAL);
expr = build_cplus_new (type, expr);
- my_friendly_assert (TREE_CODE (expr) == TARGET_EXPR, 20030729);
+ gcc_assert (TREE_CODE (expr) == TARGET_EXPR);
}
}
result_stmt_p = &TREE_OPERAND (t, 0);
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
type = TREE_TYPE (EXPR_STMT_EXPR (result_stmt));
the statement expression itself as the target's init
expr. Finally, return the target expression. */
tree init, target_expr = EXPR_STMT_EXPR (result_stmt);
- my_friendly_assert (TREE_CODE (target_expr) == TARGET_EXPR, 20030729);
+ gcc_assert (TREE_CODE (target_expr) == TARGET_EXPR);
/* The initializer will be void if the initialization is done by
AGGR_INIT_EXPR; propagate that out to the statement-expression as
returning a value directly, give it the appropriate type. */
if (VOID_TYPE_P (TREE_TYPE (result)))
TREE_TYPE (result) = type;
- else if (same_type_p (TREE_TYPE (result), type))
- ;
else
- abort ();
+ gcc_assert (same_type_p (TREE_TYPE (result), type));
}
else if (TREE_CODE (result) == STATEMENT_LIST)
/* We need to wrap a STATEMENT_LIST in a BIND_EXPR so it can have a
return error_mark_node;
/* ARGS should be a list of arguments. */
- my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
- 20020712);
+ gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
orig_fn = fn;
orig_args = args;
if (processing_template_decl)
{
- result = build (CALL_EXPR, TREE_TYPE (result), orig_fn,
- orig_args, NULL_TREE);
+ result = build3 (CALL_EXPR, TREE_TYPE (result), orig_fn,
+ orig_args, NULL_TREE);
KOENIG_LOOKUP_P (result) = koenig_p;
}
return result;
if (destructor == error_mark_node)
return error_mark_node;
- my_friendly_assert (TYPE_P (destructor), 20010905);
+ gcc_assert (TYPE_P (destructor));
if (!processing_template_decl)
{
}
}
- return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor);
+ return build3 (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor);
}
/* Finish an expression of the form CODE EXPR. */
DECL_ARTIFICIAL (decl) = 1;
end_template_decl ();
- my_friendly_assert (DECL_TEMPLATE_PARMS (tmpl), 20010110);
+ gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
return finish_template_type_parm (aggr, tmpl);
}
return;
/* We should see only one DECL at a time. */
- my_friendly_assert (TREE_CHAIN (decl) == NULL_TREE, 0);
+ gcc_assert (TREE_CHAIN (decl) == NULL_TREE);
/* Set up access control for DECL. */
TREE_PRIVATE (decl)
{
/* We also need to add this function to the
CLASSTYPE_METHOD_VEC. */
- add_method (current_class_type, decl, /*error_p=*/0);
+ add_method (current_class_type, decl);
TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
TYPE_METHODS (current_class_type) = decl;
Return a TREE_LIST containing the ACCESS_SPECIFIER and the
BASE_CLASS, or NULL_TREE if an error occurred. The
ACCESS_SPECIFIER is one of
- access_{default,public,protected_private}[_virtual]_node.*/
+ access_{default,public,protected_private}_node. For a virtual base
+ we set TREE_TYPE. */
tree
finish_base_specifier (tree base, tree access, bool virtual_p)
base = TYPE_MAIN_VARIANT (base);
}
result = build_tree_list (access, base);
- TREE_VIA_VIRTUAL (result) = virtual_p;
+ if (virtual_p)
+ TREE_TYPE (result) = integer_type_node;
}
return result;
error ("multiple declarators in template declaration");
}
-/* Issue a diagnostic that NAME cannot be found in SCOPE. */
+/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is
+ what we found when we tried to do the lookup. */
void
-qualified_name_lookup_error (tree scope, tree name)
+qualified_name_lookup_error (tree scope, tree name, tree decl)
{
if (TYPE_P (scope))
{
if (!COMPLETE_TYPE_P (scope))
error ("incomplete type `%T' used in nested name specifier", scope);
+ else if (TREE_CODE (decl) == TREE_LIST)
+ {
+ error ("reference to `%T::%D' is ambiguous", scope, name);
+ print_candidates (decl);
+ }
else
error ("`%D' is not a member of `%T'", name, scope);
}
/* If the qualifying type is non-dependent (and the name
does not name a conversion operator to a dependent
type), issue an error. */
- qualified_name_lookup_error (scope, id_expression);
+ qualified_name_lookup_error (scope, id_expression, decl);
return error_mark_node;
}
else if (!scope)
if (TYPE_P (scope) && dependent_type_p (scope))
return build_nt (SCOPE_REF, scope, id_expression);
else if (TYPE_P (scope) && DECL_P (decl))
- return build (SCOPE_REF, TREE_TYPE (decl), scope,
- id_expression);
+ return build2 (SCOPE_REF, TREE_TYPE (decl), scope,
+ id_expression);
else
return decl;
}
/* Only certain kinds of names are allowed in constant
expression. Enumerators and template parameters
have already been handled above. */
- if (integral_constant_expression_p)
+ if (integral_constant_expression_p
+ && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
{
- /* Const variables or static data members of integral or
- enumeration types initialized with constant expressions
- are OK. */
- if (TREE_CODE (decl) == VAR_DECL
- && CP_TYPE_CONST_P (TREE_TYPE (decl))
- && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
- && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
- ;
- else
+ if (!allow_non_integral_constant_expression_p)
{
- if (!allow_non_integral_constant_expression_p)
- {
- error ("`%D' cannot appear in a constant-expression", decl);
- return error_mark_node;
- }
- *non_integral_constant_expression_p = true;
+ error ("`%D' cannot appear in a constant-expression", decl);
+ return error_mark_node;
}
+ *non_integral_constant_expression_p = true;
}
if (TREE_CODE (decl) == NAMESPACE_DECL)
else if (!processing_template_decl)
decl = convert_from_reference (decl);
else if (TYPE_P (scope))
- decl = build (SCOPE_REF, TREE_TYPE (decl), scope, decl);
+ decl = build2 (SCOPE_REF, TREE_TYPE (decl), scope, decl);
}
else if (TREE_CODE (decl) == FIELD_DECL)
decl = finish_non_static_data_member (decl, current_class_ref,
else if (1)
style = pcc;
#endif
- else if (TREE_ADDRESSABLE (type))
- style = arg;
else
- /* We shouldn't build an AGGR_INIT_EXPR if we don't need any special
- handling. See build_cplus_new. */
- abort ();
+ {
+ gcc_assert (TREE_ADDRESSABLE (type));
+ style = arg;
+ }
if (style == ctor || style == arg)
{
{
/* The return type might have different cv-quals from the slot. */
tree fntype = TREE_TYPE (TREE_TYPE (fn));
-#ifdef ENABLE_CHECKING
- if (TREE_CODE (fntype) != FUNCTION_TYPE
- && TREE_CODE (fntype) != METHOD_TYPE)
- abort ();
-#endif
+
+ gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
+ || TREE_CODE (fntype) == METHOD_TYPE);
addr = convert (build_pointer_type (TREE_TYPE (fntype)), addr);
}
args = tree_cons (NULL_TREE, addr, args);
}
- call_expr = build (CALL_EXPR,
- TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
- fn, args, NULL_TREE);
+ call_expr = build3 (CALL_EXPR,
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+ fn, args, NULL_TREE);
if (style == arg)
/* Tell the backend that we've added our return slot to the argument
}
}
else
- my_friendly_assert (!DECL_THUNKS (thunk), 20031023);
+ gcc_assert (!DECL_THUNKS (thunk));
}
}
}
extract_interface_info ();
- /* If this function is marked with the constructor attribute, add it
- to the list of functions to be called along with constructors
- from static duration objects. */
- if (DECL_STATIC_CONSTRUCTOR (fn))
- static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
-
- /* If this function is marked with the destructor attribute, add it
- to the list of functions to be called along with destructors from
- static duration objects. */
- if (DECL_STATIC_DESTRUCTOR (fn))
- static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
-
if (DECL_CLONED_FUNCTION_P (fn))
{
/* If this is a clone, go through the other clones now and mark
return;
}
+ /* If this function is marked with the constructor attribute, add it
+ to the list of functions to be called along with constructors
+ from static duration objects. */
+ if (DECL_STATIC_CONSTRUCTOR (fn))
+ static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
+
+ /* If this function is marked with the destructor attribute, add it
+ to the list of functions to be called along with destructors from
+ static duration objects. */
+ if (DECL_STATIC_DESTRUCTOR (fn))
+ static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
+
+ /* We make a decision about linkage for these functions at the end
+ of the compilation. Until that point, we do not want the back
+ end to output them -- but we do want it to see the bodies of
+ these functions so that it can inline them as appropriate. */
+ if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn))
+ {
+ if (!at_eof)
+ {
+ DECL_EXTERNAL (fn) = 1;
+ DECL_NOT_REALLY_EXTERN (fn) = 1;
+ note_vague_linkage_fn (fn);
+ }
+ else
+ import_export_decl (fn);
+
+ /* If the user wants us to keep all inline functions, then mark
+ this function as needed so that finish_file will make sure to
+ output it later. */
+ if (flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
+ mark_needed (fn);
+ }
+
/* There's no reason to do any of the work here if we're only doing
semantic analysis; this code just generates RTL. */
if (flag_syntax_only)
return;
- /* Compute the appropriate object-file linkage for inline functions. */
- if (DECL_DECLARED_INLINE_P (fn))
- import_export_decl (fn);
-
function_depth++;
/* Expand or defer, at the whim of the compilation unit manager. */
if (DECL_INITIAL (dp->var)
&& DECL_INITIAL (dp->var) != error_mark_node)
{
- init = build (INIT_EXPR, void_type_node, dp->result,
- DECL_INITIAL (dp->var));
+ init = build2 (INIT_EXPR, void_type_node, dp->result,
+ DECL_INITIAL (dp->var));
DECL_INITIAL (dp->var) = error_mark_node;
}
else
/* Copy debugging information from VAR to RESULT. */
DECL_NAME (result) = DECL_NAME (var);
+ DECL_ARTIFICIAL (result) = DECL_ARTIFICIAL (var);
+ DECL_IGNORED_P (result) = DECL_IGNORED_P (var);
DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (var);
DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (var);
/* Don't forget that we take its address. */