aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog165
-rw-r--r--gcc-4.9/gcc/cp/call.c78
-rw-r--r--gcc-4.9/gcc/cp/class.c13
-rw-r--r--gcc-4.9/gcc/cp/cp-array-notation.c7
-rw-r--r--gcc-4.9/gcc/cp/cp-gimplify.c23
-rw-r--r--gcc-4.9/gcc/cp/cp-lang.c43
-rw-r--r--gcc-4.9/gcc/cp/cp-objcp-common.c465
-rw-r--r--gcc-4.9/gcc/cp/cp-tree.h49
-rw-r--r--gcc-4.9/gcc/cp/decl.c47
-rw-r--r--gcc-4.9/gcc/cp/decl2.c176
-rw-r--r--gcc-4.9/gcc/cp/error.c5
-rw-r--r--gcc-4.9/gcc/cp/friend.c10
-rw-r--r--gcc-4.9/gcc/cp/init.c85
-rw-r--r--gcc-4.9/gcc/cp/mangle.c33
-rw-r--r--gcc-4.9/gcc/cp/method.c6
-rw-r--r--gcc-4.9/gcc/cp/name-lookup.c54
-rw-r--r--gcc-4.9/gcc/cp/name-lookup.h1
-rw-r--r--gcc-4.9/gcc/cp/parser.c148
-rw-r--r--gcc-4.9/gcc/cp/parser.h9
-rw-r--r--gcc-4.9/gcc/cp/pt.c55
-rw-r--r--gcc-4.9/gcc/cp/rtti.c10
-rw-r--r--gcc-4.9/gcc/cp/semantics.c54
-rw-r--r--gcc-4.9/gcc/cp/tree.c11
-rw-r--r--gcc-4.9/gcc/cp/typeck.c6
-rw-r--r--gcc-4.9/gcc/cp/typeck2.c16
25 files changed, 1345 insertions, 224 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog
index f9cf11884..f406b27b7 100644
--- a/gcc-4.9/gcc/cp/ChangeLog
+++ b/gcc-4.9/gcc/cp/ChangeLog
@@ -1,3 +1,168 @@
+2014-07-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/61661
+ * semantics.c (reduced_constant_expression_p): Handle CONSTRUCTOR.
+
+2014-07-01 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ PR c++/58753
+ PR c++/58930
+ PR c++/58704
+
+ Backported from mainline
+ 2014-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * typeck2.c (digest_nsdmi_init): New.
+ * parser.c (cp_parser_late_parse_one_default_arg): Use it.
+ * init.c (get_nsdmi): Likewise.
+ * cp-tree.h (digest_nsdmi_init): Declare.
+
+2014-06-30 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/58781
+ PR c++/60249
+ PR c++/59867
+ * parser.c (cp_parser_userdef_string_literal()): Take a tree
+ not a cp_token*. (cp_parser_string_literal(): Don't hack
+ the token stream!
+
+2014-06-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/61647
+ * pt.c (type_dependent_expression_p): Check BASELINK_OPTYPE.
+
+ PR c++/61566
+ * mangle.c (decl_mangling_context): Look through a TEMPLATE_DECL.
+
+2014-06-30 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2014-06-25 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_clauses): Make sure
+ OMP_CLAUSE_LINEAR_STEP has correct type.
+
+ 2014-06-18 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cxx_omp_finish_clause): Add a gimple_seq *
+ argument.
+ * cp-tree.h (cxx_omp_finish_clause): Adjust prototype.
+
+2014-06-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/61539
+ * pt.c (unify_one_argument): Type/expression mismatch just causes
+ deduction failure.
+
+ DR 1030
+ PR c++/51253
+ PR c++/61382
+ * cp-tree.h (CALL_EXPR_LIST_INIT_P): New.
+ * call.c (struct z_candidate): Add flags field.
+ (add_candidate): Add flags parm.
+ (add_function_candidate, add_conv_candidate, build_builtin_candidate)
+ (add_template_candidate_real): Pass it.
+ (build_over_call): Set CALL_EXPR_LIST_INIT_P.
+ * tree.c (build_aggr_init_expr): Copy it.
+ * semantics.c (simplify_aggr_init_expr): Copy it.
+ * cp-gimplify.c (cp_gimplify_expr): Handle it.
+
+ PR c++/61488
+ * pt.c (check_valid_ptrmem_cst_expr): Fix for template context.
+
+ PR c++/61500
+ * tree.c (lvalue_kind): Handle MEMBER_REF and DOTSTAR_EXPR.
+
+2014-06-30 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ PR middle-end/57541
+ * cp-array-notation.c (expand_sec_reduce_builtin):
+ Check that bultin argument is correct.
+ * call.c (build_cxx_call): Check for 0 arguments in builtin call.
+
+2014-06-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/61433
+ * error.c (dump_template_bindings): Don't tsubst in a clone.
+
+2014-06-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/61614
+ * semantics.c (finish_compound_literal): Revert r204228.
+
+2014-06-26 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/61537
+ * parser.c (cp_parser_elaborated_type_specifier): Only consider template
+ parameter lists outside of function parameter scope.
+
+2014-06-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/61242
+ * call.c (build_aggr_conv): Ignore passed in flags.
+ (build_array_conv, build_complex_conv): Likewise.
+
+2014-06-24 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_for_loop): For
+ #pragma omp parallel for simd move lastprivate clause from parallel
+ to for rather than simd.
+
+2014-06-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/59296
+ * call.c (add_function_candidate): Avoid special 'this' handling
+ if we have a ref-qualifier.
+
+ PR c++/61556
+ * call.c (build_over_call): Call build_this in template path.
+
+2014-06-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/59296
+ * call.c (add_function_candidate): Set LOOKUP_NO_RVAL_BIND
+ |LOOKUP_NO_TEMP_BIND for ref-qualifier handling.
+
+ PR c++/61507
+ * pt.c (resolve_overloaded_unification): Preserve
+ ARGUMENT_PACK_EXPLICIT_ARGS.
+
+2014-06-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/60605
+ * pt.c (check_default_tmpl_args): Check DECL_LOCAL_FUNCTION_P.
+
+2014-06-18 Siva Chandra Reddy <sivachandra@google.com>
+
+ PR debug/57519
+ * class.c (handle_using_decl): Pass the correct scope to
+ cp_emit_debug_info_for_using.
+
+2014-06-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/61343
+ * decl.c (check_initializer): Maybe clear
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+
+2014-06-04 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ PR c/58942
+ * c-c++-common/cilk-plus/AN/pr58942.c: Check for correct handling of
+ the case with a pointer.
+
+2014-06-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/61134
+ * pt.c (pack_deducible_p): Handle canonicalization.
+
+2014-05-21 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ PR c/60189
+ * parser.c (cp_parser_postfix_expression): Move handling of cilk_sync
+ from here to...
+ (cp_parser_statement): ...here. Make sure only semicolon can go after
+ Cilk_sync.
+
2014-05-13 Jason Merrill <jason@redhat.com>
PR c++/61151
diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c
index 57e08cb8e..2f24fd49b 100644
--- a/gcc-4.9/gcc/cp/call.c
+++ b/gcc-4.9/gcc/cp/call.c
@@ -206,7 +206,7 @@ static conversion *maybe_handle_ref_bind (conversion **);
static void maybe_handle_implicit_object (conversion **);
static struct z_candidate *add_candidate
(struct z_candidate **, tree, tree, const vec<tree, va_gc> *, size_t,
- conversion **, tree, tree, int, struct rejection_reason *);
+ conversion **, tree, tree, int, struct rejection_reason *, int);
static tree source_type (conversion *);
static void add_warning (struct z_candidate *, struct z_candidate *);
static bool reference_compatible_p (tree, tree);
@@ -520,7 +520,6 @@ struct z_candidate {
sequence from the type returned by FN to the desired destination
type. */
conversion *second_conv;
- int viable;
struct rejection_reason *reason;
/* If FN is a member function, the binfo indicating the path used to
qualify the name of FN at the call site. This path is used to
@@ -538,6 +537,10 @@ struct z_candidate {
tree explicit_targs;
candidate_warning *warnings;
z_candidate *next;
+ int viable;
+
+ /* The flags active in add_candidate. */
+ int flags;
};
/* Returns true iff T is a null pointer constant in the sense of
@@ -886,7 +889,9 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
if (ctor == error_mark_node)
return NULL;
- flags |= LOOKUP_NO_NARROWING;
+ /* The conversions within the init-list aren't affected by the enclosing
+ context; they're always simple copy-initialization. */
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
for (; field; field = next_initializable_field (DECL_CHAIN (field)))
{
@@ -959,6 +964,8 @@ build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
return NULL;
}
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
+
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
{
conversion *sub
@@ -1003,6 +1010,8 @@ build_complex_conv (tree type, tree ctor, int flags,
if (len != 2)
return NULL;
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
+
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
{
conversion *sub
@@ -1810,7 +1819,8 @@ add_candidate (struct z_candidate **candidates,
tree fn, tree first_arg, const vec<tree, va_gc> *args,
size_t num_convs, conversion **convs,
tree access_path, tree conversion_path,
- int viable, struct rejection_reason *reason)
+ int viable, struct rejection_reason *reason,
+ int flags)
{
struct z_candidate *cand = (struct z_candidate *)
conversion_obstack_alloc (sizeof (struct z_candidate));
@@ -1825,6 +1835,7 @@ add_candidate (struct z_candidate **candidates,
cand->viable = viable;
cand->reason = reason;
cand->next = *candidates;
+ cand->flags = flags;
*candidates = cand;
return cand;
@@ -1994,6 +2005,9 @@ add_function_candidate (struct z_candidate **candidates,
object parameter has reference type. */
bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
parmtype = cp_build_reference_type (parmtype, rv);
+ /* The special handling of 'this' conversions in compare_ics
+ does not apply if there is a ref-qualifier. */
+ is_this = false;
}
else
{
@@ -2061,7 +2075,7 @@ add_function_candidate (struct z_candidate **candidates,
out:
return add_candidate (candidates, fn, orig_first_arg, args, len, convs,
- access_path, conversion_path, viable, reason);
+ access_path, conversion_path, viable, reason, flags);
}
/* Create an overload candidate for the conversion function FN which will
@@ -2163,7 +2177,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
}
return add_candidate (candidates, totype, first_arg, arglist, len, convs,
- access_path, conversion_path, viable, reason);
+ access_path, conversion_path, viable, reason, flags);
}
static void
@@ -2238,7 +2252,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
num_convs, convs,
/*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE,
- viable, reason);
+ viable, reason, flags);
}
static bool
@@ -3056,7 +3070,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
return cand;
fail:
return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL,
- access_path, conversion_path, 0, reason);
+ access_path, conversion_path, 0, reason, flags);
}
@@ -4020,8 +4034,9 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
if (size_check != NULL_TREE)
{
tree errval = TYPE_MAX_VALUE (sizetype);
- /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length call. */
- if (cxx_dialect >= cxx11 && flag_exceptions && 0)
+ if (cxx_dialect >= cxx11 && flag_exceptions
+ /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length call. */
+ && !TARGET_ANDROID)
errval = throw_bad_array_new_length ();
*size = fold_build3 (COND_EXPR, sizetype, size_check,
original_size, errval);
@@ -5743,8 +5758,22 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
usual deallocation function."
So (void*) beats (void*, size_t). */
- if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
- break;
+ /* If type is not void, pick (void*, size_t) version (which comes
+ first). */
+ if (!flag_sized_delete || TREE_CODE (type) == VOID_TYPE )
+ {
+ /* If -fsized-delete is not passed or if a void * is deleted,
+ prefer delete (void *) version. */
+ if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
+ break;
+ }
+ else
+ {
+ /* If -fsized-delete is passed and it is not a void *,
+ prefer delete (void *, size_t) version. */
+ if (FUNCTION_ARG_CHAIN (fn) != void_list_node)
+ break;
+ }
}
}
@@ -6761,7 +6790,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
++nargs;
alcarray = XALLOCAVEC (tree, nargs);
- alcarray[0] = first_arg;
+ alcarray[0] = build_this (first_arg);
FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
alcarray[ix + 1] = arg;
argarray = alcarray;
@@ -7229,7 +7258,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return error_mark_node;
}
- return build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
+ tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
+ if (TREE_CODE (call) == CALL_EXPR
+ && (cand->flags & LOOKUP_LIST_INIT_CTOR))
+ CALL_EXPR_LIST_INIT_P (call) = true;
+ return call;
}
/* Build and return a call to FN, using NARGS arguments in ARGARRAY.
@@ -7271,6 +7304,11 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
|| bif == BUILT_IN_CILKPLUS_SEC_REDUCE
|| bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
{
+ if (call_expr_nargs (fn) == 0)
+ {
+ error_at (EXPR_LOCATION (fn), "Invalid builtin arguments");
+ return error_mark_node;
+ }
/* for bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO or
BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO or
BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO or
@@ -8456,10 +8494,11 @@ compare_ics (conversion *ics1, conversion *ics2)
/* [over.ics.rank]
--S1 and S2 are reference bindings (_dcl.init.ref_) and neither refers
- to an implicit object parameter, and either S1 binds an lvalue reference
- to an lvalue and S2 binds an rvalue reference or S1 binds an rvalue
- reference to an rvalue and S2 binds an lvalue reference
- (C++0x draft standard, 13.3.3.2)
+ to an implicit object parameter of a non-static member function
+ declared without a ref-qualifier, and either S1 binds an lvalue
+ reference to an lvalue and S2 binds an rvalue reference or S1 binds an
+ rvalue reference to an rvalue and S2 binds an lvalue reference (C++0x
+ draft standard, 13.3.3.2)
--S1 and S2 are reference bindings (_dcl.init.ref_), and the
types to which the references refer are the same type except for
@@ -9232,6 +9271,9 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
tree name;
TREE_STATIC (var) = TREE_STATIC (decl);
+ /* Capture the current module info for statics. */
+ if (L_IPO_COMP_MODE && TREE_STATIC (var))
+ varpool_node_for_decl (var);
DECL_TLS_MODEL (var) = DECL_TLS_MODEL (decl);
name = mangle_ref_init_variable (decl);
DECL_NAME (var) = name;
diff --git a/gcc-4.9/gcc/cp/class.c b/gcc-4.9/gcc/cp/class.c
index 334bfd5ee..265afc486 100644
--- a/gcc-4.9/gcc/cp/class.c
+++ b/gcc-4.9/gcc/cp/class.c
@@ -1300,7 +1300,7 @@ handle_using_decl (tree using_decl, tree t)
old_value = NULL_TREE;
}
- cp_emit_debug_info_for_using (decl, USING_DECL_SCOPE (using_decl));
+ cp_emit_debug_info_for_using (decl, t);
if (is_overloaded_fn (decl))
flist = decl;
@@ -8223,12 +8223,11 @@ static void
dump_class_hierarchy (tree t)
{
int flags;
- FILE *stream = dump_begin (TDI_class, &flags);
+ FILE *stream = get_dump_info (TDI_class, &flags);
if (stream)
{
dump_class_hierarchy_1 (stream, flags, t);
- dump_end (TDI_class, stream);
}
}
@@ -8258,7 +8257,7 @@ static void
dump_vtable (tree t, tree binfo, tree vtable)
{
int flags;
- FILE *stream = dump_begin (TDI_class, &flags);
+ FILE *stream = get_dump_info (TDI_class, &flags);
if (!stream)
return;
@@ -8281,15 +8280,13 @@ dump_vtable (tree t, tree binfo, tree vtable)
dump_array (stream, vtable);
fprintf (stream, "\n");
}
-
- dump_end (TDI_class, stream);
}
static void
dump_vtt (tree t, tree vtt)
{
int flags;
- FILE *stream = dump_begin (TDI_class, &flags);
+ FILE *stream = get_dump_info (TDI_class, &flags);
if (!stream)
return;
@@ -8301,8 +8298,6 @@ dump_vtt (tree t, tree vtt)
dump_array (stream, vtt);
fprintf (stream, "\n");
}
-
- dump_end (TDI_class, stream);
}
/* Dump a function or thunk and its thunkees. */
diff --git a/gcc-4.9/gcc/cp/cp-array-notation.c b/gcc-4.9/gcc/cp/cp-array-notation.c
index 65b8bcb81..fed60c953 100644
--- a/gcc-4.9/gcc/cp/cp-array-notation.c
+++ b/gcc-4.9/gcc/cp/cp-array-notation.c
@@ -250,7 +250,10 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
if (!find_rank (location, an_builtin_fn, an_builtin_fn, true, &rank))
return error_mark_node;
if (rank == 0)
- return an_builtin_fn;
+ {
+ error_at (location, "Invalid builtin arguments");
+ return error_mark_node;
+ }
else if (rank > 1
&& (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
|| an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND))
@@ -340,6 +343,8 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
array_ind_value = get_temp_regvar (TREE_TYPE (func_parm), func_parm);
array_op0 = (*array_operand)[0];
+ if (TREE_CODE (array_op0) == INDIRECT_REF)
+ array_op0 = TREE_OPERAND (array_op0, 0);
switch (an_type)
{
case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
diff --git a/gcc-4.9/gcc/cp/cp-gimplify.c b/gcc-4.9/gcc/cp/cp-gimplify.c
index ef4b04372..3dc32e6cf 100644
--- a/gcc-4.9/gcc/cp/cp-gimplify.c
+++ b/gcc-4.9/gcc/cp/cp-gimplify.c
@@ -723,6 +723,27 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
&& !seen_error ())
return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+ /* DR 1030 says that we need to evaluate the elements of an
+ initializer-list in forward order even when it's used as arguments to
+ a constructor. So if the target wants to evaluate them in reverse
+ order and there's more than one argument other than 'this', gimplify
+ them in order. */
+ ret = GS_OK;
+ if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p)
+ && call_expr_nargs (*expr_p) > 2)
+ {
+ int nargs = call_expr_nargs (*expr_p);
+ location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
+ for (int i = 1; i < nargs; ++i)
+ {
+ enum gimplify_status t
+ = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
+ if (t == GS_ERROR)
+ ret = GS_ERROR;
+ }
+ }
+ break;
+
default:
ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
break;
@@ -1578,7 +1599,7 @@ cxx_omp_predetermined_sharing (tree decl)
/* Finalize an implicitly determined clause. */
void
-cxx_omp_finish_clause (tree c)
+cxx_omp_finish_clause (tree c, gimple_seq *)
{
tree decl, inner_type;
bool make_shared = false;
diff --git a/gcc-4.9/gcc/cp/cp-lang.c b/gcc-4.9/gcc/cp/cp-lang.c
index c28c07a9d..22f8e4bbb 100644
--- a/gcc-4.9/gcc/cp/cp-lang.c
+++ b/gcc-4.9/gcc/cp/cp-lang.c
@@ -37,6 +37,7 @@ enum c_language_kind c_language = clk_cxx;
static void cp_init_ts (void);
static const char * cxx_dwarf_name (tree t, int verbosity);
static enum classify_record cp_classify_record (tree type);
+static bool cp_user_conv_function_p (tree);
static tree cp_eh_personality (void);
static tree get_template_innermost_arguments_folded (const_tree);
static tree get_template_argument_pack_elems_folded (const_tree);
@@ -77,11 +78,46 @@ static tree get_template_argument_pack_elems_folded (const_tree);
#define LANG_HOOKS_DWARF_NAME cxx_dwarf_name
#undef LANG_HOOKS_INIT_TS
#define LANG_HOOKS_INIT_TS cp_init_ts
+#undef LANG_HOOKS_USER_CONV_FUNCTION
+#define LANG_HOOKS_USER_CONV_FUNCTION cp_user_conv_function_p
#undef LANG_HOOKS_EH_PERSONALITY
#define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
#undef LANG_HOOKS_EH_RUNTIME_TYPE
#define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
+
+/* LIPO support. */
+#undef LANG_HOOKS_ADD_BUILT_IN_DECL
+#define LANG_HOOKS_ADD_BUILT_IN_DECL cp_add_built_in_decl
+#undef LANG_HOOKS_SAVE_BUILT_IN_PRE
+#define LANG_HOOKS_SAVE_BUILT_IN_PRE cp_save_built_in_decl_pre_parsing
+#undef LANG_HOOKS_RESTORE_BUILT_IN_PRE
+#define LANG_HOOKS_RESTORE_BUILT_IN_PRE cp_restore_built_in_decl_pre_parsing
+#undef LANG_HOOKS_SAVE_BUILT_IN_POST
+#define LANG_HOOKS_SAVE_BUILT_IN_POST cp_save_built_in_decl_post_parsing
+#undef LANG_HOOKS_RESTORE_BUILT_IN_POST
+#define LANG_HOOKS_RESTORE_BUILT_IN_POST cp_restore_built_in_decl_post_parsing
+#undef LANG_HOOKS_CLEAR_NAME_BINDINGS
+#define LANG_HOOKS_CLEAR_NAME_BINDINGS cp_clear_global_name_bindings
+#undef LANG_HOOKS_HAS_GLOBAL_NAME
+#define LANG_HOOKS_HAS_GLOBAL_NAME cp_is_non_sharable_global_decl
+#undef LANG_HOOKS_GET_LANG_DECL_SIZE
+#define LANG_HOOKS_GET_LANG_DECL_SIZE cp_get_lang_decl_size
+#undef LANG_HOOKS_DUP_LANG_TYPE
+#define LANG_HOOKS_DUP_LANG_TYPE cp_lipo_dup_lang_type
+#undef LANG_HOOKS_COPY_LANG_TYPE
+#define LANG_HOOKS_COPY_LANG_TYPE cp_lipo_copy_lang_type
+#undef LANG_HOOKS_PROCESS_PENDING_DECLS
+#define LANG_HOOKS_PROCESS_PENDING_DECLS cp_process_pending_declarations
+#undef LANG_HOOKS_CLEAR_DEFFERED_FNS
+#define LANG_HOOKS_CLEAR_DEFFERED_FNS cp_clear_deferred_fns
+#undef LANG_HOOKS_IS_GENERATED_TYPE
+#define LANG_HOOKS_IS_GENERATED_TYPE cp_is_compiler_generated_type
+#undef LANG_HOOKS_CMP_LANG_TYPE
+#define LANG_HOOKS_CMP_LANG_TYPE cp_cmp_lang_type
+
+
+
/* Each front end provides its own lang hook initializer. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -134,6 +170,13 @@ cp_classify_record (tree type)
return RECORD_IS_STRUCT;
}
+static bool
+cp_user_conv_function_p (tree decl)
+{
+ return DECL_CONV_FN_P (decl);
+}
+
+
static GTY(()) tree cp_eh_personality_decl;
static tree
diff --git a/gcc-4.9/gcc/cp/cp-objcp-common.c b/gcc-4.9/gcc/cp/cp-objcp-common.c
index aa0ff839c..e350bb3f3 100644
--- a/gcc-4.9/gcc/cp/cp-objcp-common.c
+++ b/gcc-4.9/gcc/cp/cp-objcp-common.c
@@ -25,12 +25,14 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "cp-tree.h"
#include "c-family/c-common.h"
+#include "cgraph.h"
#include "langhooks.h"
#include "langhooks-def.h"
#include "diagnostic.h"
#include "debug.h"
#include "cxx-pretty-print.h"
#include "cp-objcp-common.h"
+#include "l-ipo.h"
#include <new> // For placement new.
@@ -164,15 +166,476 @@ cp_function_decl_explicit_p (tree decl)
&& DECL_NONCONVERTING_P (decl));
}
-/* Stubs to keep c-opts.c happy. */
+/* LIPO support */
+
+typedef struct GTY (()) sb
+{
+ tree decl;
+ tree decl_init_copy; /* copy at the start of file parsing. */
+ tree decl_fini_copy; /* copy at the end of module_scope. */
+ tree id;
+ cxx_binding *binding;
+ /* binding->value may get overwritten during parsing due to
+ an incompatible delcaration in the same scope (e.g. clog),
+ so we need to expliclitly save the binding value. */
+ tree binding_value;
+ /* The binding value in the previous scope: std namespace. */
+ tree std_binding_value;
+ tree real_type_value;
+} saved_builtin;
+
+static GTY (()) vec<saved_builtin, va_gc> *saved_builtins = NULL;
+
+/* Return true if the type is not user defined. */
+
+bool
+cp_is_compiler_generated_type (tree t)
+{
+ if (TYPE_PTRMEMFUNC_P (t))
+ return true;
+ return false;
+}
+
+/* Clear symbol binding for name ID. */
+
+void
+cp_clear_global_name_bindings (tree id)
+{
+ if (id)
+ IDENTIFIER_NAMESPACE_BINDINGS (id) = NULL;
+}
+
+/* Return true if DECL is scoped in global/namespace scope, otherwise
+ return false. This is a langhook method that is used to select declarations
+ that needs to be explicitly popped out the global/namespace scope
+ at the end of parsing the file. */
+
+bool
+cp_is_non_sharable_global_decl (tree decl, void *scope)
+{
+ cp_binding_level *global_scope, *cur_scope;
+
+ cur_scope = (cp_binding_level *) scope;
+ global_scope = NAMESPACE_LEVEL (global_namespace);
+ if (cur_scope->kind != sk_namespace && cur_scope != global_scope)
+ return false;
+
+ /* Type info objects are compiler created -- allow such
+ decls to be shared (treated as other builtins) across modules. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl))
+ return false;
+
+ return true;
+}
+
+/* Duplicate language specific type information from SRC
+ to DEST. */
+
+void
+cp_lipo_dup_lang_type (tree src, tree dest)
+{
+ struct lang_type *lang_type_clone = 0;
+ /* TODO check size. */
+ lang_type_clone = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
+ *lang_type_clone = *TYPE_LANG_SPECIFIC (src);
+ TYPE_LANG_SPECIFIC (dest) = lang_type_clone;
+
+ TYPE_CACHED_VALUES_P (dest) = TYPE_CACHED_VALUES_P (src);
+ if (TYPE_CACHED_VALUES_P (src))
+ TYPE_CACHED_VALUES (dest) = TYPE_CACHED_VALUES (src);
+ /* Main variant's clone's main variant should be itself. */
+ TYPE_MAIN_VARIANT (dest) = dest;
+ /* Now copy the subdecl.
+ Do not reorder this with previous statement -- it
+ depends on the result of previous one. */
+ TYPE_MAIN_DECL(dest) = TYPE_MAIN_DECL (src);
+}
+
+
+/* Copy DEST into SRC. */
+
+void
+cp_lipo_copy_lang_type (tree src, tree dest)
+{
+ struct lang_type *old_ls;
+ unsigned old_uid;
+
+ old_ls = TYPE_LANG_SPECIFIC (dest);
+ *old_ls = *(TYPE_LANG_SPECIFIC (src));
+ old_uid = TYPE_UID (dest);
+ memcpy (dest, src, tree_size (dest));
+
+ TYPE_UID (dest) = old_uid;
+ TYPE_LANG_SPECIFIC (dest) = old_ls;
+ /* recover main variant. */
+ TYPE_MAIN_VARIANT (dest) = dest;
+ TYPE_MAIN_DECL (dest) = TYPE_MAIN_DECL (src);
+}
+
+/* Return the actual size of the lang_decl struct for
+ decl T. */
+
+int
+cp_get_lang_decl_size (tree t)
+{
+ size_t size;
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ size = sizeof (struct lang_decl_fn);
+ else if (TREE_CODE (t) == NAMESPACE_DECL)
+ size = sizeof (struct lang_decl_ns);
+ else if (TREE_CODE (t) == PARM_DECL)
+ size = sizeof (struct lang_decl_parm);
+ else if (LANG_DECL_HAS_MIN (t))
+ size = sizeof (struct lang_decl_min);
+ else
+ gcc_unreachable ();
+
+ return (int) size;
+}
+
+/* Return 1 if template arguments TA1 and TA2 is compatible.
+ Return 0 otherwise. */
+
+static int
+cmp_templ_arg (tree ta1, tree ta2)
+{
+ if (ARGUMENT_PACK_P (ta1))
+ {
+ int n, i;
+ if (!ARGUMENT_PACK_P (ta2))
+ return 0;
+ tree pack1 = ARGUMENT_PACK_ARGS (ta1);
+ tree pack2 = ARGUMENT_PACK_ARGS (ta2);
+ n = TREE_VEC_LENGTH (pack1);
+ if (n != TREE_VEC_LENGTH (pack2))
+ return 0;
+ for (i = 0; i < n ; i++)
+ {
+ if (!cmp_templ_arg (TREE_VEC_ELT (pack1, i),
+ TREE_VEC_ELT (pack2, i)))
+ return 0;
+ }
+ return 1;
+ }
+ else if (TYPE_P (ta1))
+ {
+ if (!TYPE_P (ta2))
+ return 0;
+
+ return lipo_cmp_type (ta1, ta2);
+ }
+ else if (TREE_CODE (ta1) == TEMPLATE_DECL)
+ {
+ if (TREE_CODE (ta2) != TEMPLATE_DECL)
+ return 0;
+
+ /* compare name -- need context comparison: */
+ return !strcmp (IDENTIFIER_POINTER (DECL_NAME (ta1)),
+ IDENTIFIER_POINTER (DECL_NAME (ta2)));
+ }
+ else /* integer expression */
+ {
+ if (TREE_CODE (ta1) != TREE_CODE (ta2))
+ return 0;
+ if (TREE_CODE (ta1) == INTEGER_CST)
+ return (TREE_INT_CST_HIGH (ta1) == TREE_INT_CST_HIGH (ta2)
+ && TREE_INT_CST_LOW (ta1) == TREE_INT_CST_LOW (ta2));
+ else if (TREE_CODE (ta1) == ADDR_EXPR)
+ {
+ tree td1, td2;
+
+ td1 = TREE_OPERAND (ta1, 0);
+ td2 = TREE_OPERAND (ta2, 0);
+ if (TREE_CODE (td1) != TREE_CODE (td2))
+ return 0;
+ if (TREE_CODE (td1) == FUNCTION_DECL)
+ {
+ tree id1, id2;
+
+ if (!TREE_PUBLIC (td1) || !TREE_PUBLIC (td2))
+ return td1 == td2;
+
+ id1 = DECL_ASSEMBLER_NAME (td1);
+ id2 = DECL_ASSEMBLER_NAME (td2);
+ return !strcmp (IDENTIFIER_POINTER (id1),
+ IDENTIFIER_POINTER (id2));
+ }
+ else
+ {
+ gcc_assert (TREE_CODE (td1) == VAR_DECL);
+ return real_varpool_node (td1) == real_varpool_node (td2);
+ }
+ }
+ else
+ /* Be conservative (from aliasing point of view) for now (TODO) */
+ return 1;
+ }
+}
+
+/* Return 1 if template parameters of T1 and T2
+ are compatible, returns 0 otherwise. */
+
+static int
+cmp_templ_parms (tree t1, tree t2)
+{
+ int n_lvl = 1, i;
+ tree a1, a2;
+ tree args1 = CLASSTYPE_TI_ARGS (t1);
+ tree args2 = CLASSTYPE_TI_ARGS (t2);
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args1)
+ && !TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args2))
+ return 0;
+ if (!TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args1)
+ && TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args2))
+ return 0;
+
+ if (TREE_VEC_LENGTH (args1) != TREE_VEC_LENGTH (args2))
+ return 0;
+
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args1))
+ n_lvl = TREE_VEC_LENGTH (args1);
+
+ i = 0;
+ if (n_lvl == 1)
+ {
+ a1 = args1;
+ a2 = args2;
+ }
+ else
+ {
+ a1 = TREE_VEC_ELT (args1, 0);
+ a2 = TREE_VEC_ELT (args2, 0);
+ }
+
+ while (i < n_lvl)
+ {
+ int len1, len2, j;
+
+ len1 = TREE_VEC_LENGTH (a1);
+ len2 = TREE_VEC_LENGTH (a2);
+
+ if (len1 != len2)
+ return 0;
+
+ for (j = 0; j < len1; j++)
+ {
+ tree ta1, ta2;
+
+ ta1 = TREE_VEC_ELT (a1, j);
+ ta2 = TREE_VEC_ELT (a2, j);
+
+ if (!cmp_templ_arg (ta1, ta2))
+ return 0;
+ }
+ i++;
+ if (i < n_lvl)
+ {
+ a1 = TREE_VEC_ELT (args1, i);
+ a2 = TREE_VEC_ELT (args2, i);
+ }
+ }
+ return 1;
+}
+
+/* Return 1 if type T1 and T2 are compatible. Type comparison
+ is based on type kind and name. */
+
+int
+cp_cmp_lang_type (tree t1, tree t2)
+{
+ int templ1, templ2;
+
+ /* Now check if the type is a template instantiation. */
+ templ1 = (TYPE_LANG_SPECIFIC (t1) && CLASSTYPE_TEMPLATE_INFO (t1));
+ templ2 = (TYPE_LANG_SPECIFIC (t2) && CLASSTYPE_TEMPLATE_INFO (t2));
+
+ if ((templ1 && !templ2) || (!templ1 && templ2))
+ return 0;
+ if (!templ1 && !templ2)
+ return 1;
+
+ return cmp_templ_parms (t1, t2);
+}
+
+/* Push DECL to the list of builtins declared by the
+ frontend. */
+
+void
+cp_add_built_in_decl (tree decl)
+{
+ saved_builtin *sb;
+
+ if (!flag_dyn_ipa)
+ return;
+
+ if (at_eof)
+ return;
+
+ if (parser_parsing_start)
+ return;
+
+ sb = vec_safe_push (saved_builtins, saved_builtin ());
+ sb->decl = decl;
+ sb->decl_init_copy = NULL;
+ sb->decl_fini_copy = NULL;
+ sb->id = NULL;
+ sb->binding = NULL;
+ sb->real_type_value = NULL;
+ sb->binding_value = NULL;
+ sb->std_binding_value = NULL;
+}
+
+/* Save SB->decl and its name id's binding values. */
+
+static void
+save_built_in_decl_pre_parsing_1 (saved_builtin *sb)
+{
+ tree decl = sb->decl;
+
+ sb->decl_init_copy = lipo_save_decl (decl);
+ sb->decl_fini_copy = NULL;
+ sb->id = NULL;
+ sb->binding = NULL;
+ sb->real_type_value = NULL;
+ sb->binding_value = NULL;
+ sb->std_binding_value = NULL;
+ if (TREE_CODE_CLASS (TREE_CODE (decl)) != tcc_type)
+ sb->id = DECL_NAME (decl);
+ else
+ {
+ tree id;
+ id = TYPE_NAME (decl);
+ if (TREE_CODE (id) == TYPE_DECL)
+ id = DECL_NAME (id);
+ sb->id = id;
+ }
+
+ if (sb->id)
+ {
+ sb->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (sb->id);
+ sb->binding = IDENTIFIER_NAMESPACE_BINDINGS (sb->id);
+ if (sb->binding)
+ {
+ sb->binding_value = sb->binding->value;
+
+ if (sb->binding->previous)
+ sb->std_binding_value = sb->binding->previous->value;
+ }
+ }
+ else
+ {
+ sb->real_type_value = NULL;
+ sb->binding = NULL;
+ }
+
+ return;
+}
+
+/* Add builtin types into the list of builtins. */
+
+static void
+add_built_in_type_node (void)
+{
+ tree type_info_node;
+
+ type_info_node = TYPE_MAIN_VARIANT (const_type_info_type_node);
+ cp_add_built_in_decl (type_info_node);
+}
+
+/* Save the tree (by making a copy) and binding values for
+ builtins before parsing start. */
+
+void
+cp_save_built_in_decl_pre_parsing (void)
+{
+ size_t i;
+ saved_builtin *bi;
+
+ add_built_in_type_node ();
+
+ for (i = 0; saved_builtins->iterate (i, &bi); ++i)
+ save_built_in_decl_pre_parsing_1 (bi);
+}
+
+/* Restore builtins and their bindings to their values
+ before parsing. */
+
+void
+cp_restore_built_in_decl_pre_parsing (void)
+{
+ size_t i;
+ saved_builtin *bi;
+
+ for (i = 0; saved_builtins->iterate (i, &bi); ++i)
+ {
+ tree decl = bi->decl;
+
+ lipo_restore_decl (decl, bi->decl_init_copy);
+
+ if (bi->id)
+ {
+ if (bi->binding)
+ {
+ bi->binding->value = bi->binding_value;
+ if (bi->binding->previous)
+ bi->binding->previous->value = bi->std_binding_value;
+ }
+ IDENTIFIER_NAMESPACE_BINDINGS (bi->id) = bi->binding;
+ REAL_IDENTIFIER_TYPE_VALUE (bi->id) = bi->real_type_value;
+ }
+ }
+ DECL_NAMESPACE_USING (global_namespace) = NULL;
+}
+
+/* Save the tree (by making a copy) and binding values for
+ builtins after parsing of a file. */
+
+void
+cp_save_built_in_decl_post_parsing (void)
+{
+ size_t i;
+ saved_builtin *bi;
+
+ for (i = 0; saved_builtins->iterate (i, &bi); ++i)
+ {
+ if (!TREE_STATIC (bi->decl) || DECL_ARTIFICIAL (bi->decl))
+ continue;
+ /* Remember the defining module. */
+ cgraph_link_node (cgraph_get_create_node (bi->decl));
+ if (!bi->decl_fini_copy)
+ bi->decl_fini_copy = lipo_save_decl (bi->decl);
+ else
+ gcc_assert (TREE_STATIC (bi->decl_fini_copy));
+ }
+}
+
+/* Restore builtins and their bindings to their post parsing values. */
+
+void
+cp_restore_built_in_decl_post_parsing (void)
+{
+ unsigned i;
+ saved_builtin *bi;
+
+ for (i = 0; saved_builtins->iterate (i, &bi); ++i)
+ {
+ tree decl = bi->decl;
+ /* Now restore the decl's state */
+ if (bi->decl_fini_copy)
+ lipo_restore_decl (decl, bi->decl_fini_copy);
+ }
+}
+
void
push_file_scope (void)
{
+ push_module_scope ();
}
void
pop_file_scope (void)
{
+ pop_module_scope ();
}
/* c-pragma.c needs to query whether a decl has extern "C" linkage. */
diff --git a/gcc-4.9/gcc/cp/cp-tree.h b/gcc-4.9/gcc/cp/cp-tree.h
index e9fe86ee4..e6323e7eb 100644
--- a/gcc-4.9/gcc/cp/cp-tree.h
+++ b/gcc-4.9/gcc/cp/cp-tree.h
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "hashtab.h"
#include "vec.h"
+#include "l-ipo.h"
/* In order for the format checking to accept the C++ front end
diagnostic framework extensions, you must include this file before
@@ -101,12 +102,14 @@ c-common.h, not after.
FNDECL_USED_AUTO (in FUNCTION_DECL)
DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE)
REF_PARENTHESIZED_P (in COMPONENT_REF, SCOPE_REF)
+ AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
ICS_BAD_FLAG (in _CONV)
FN_TRY_BLOCK_P (in TRY_BLOCK)
IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE)
BIND_EXPR_BODY_BLOCK (in BIND_EXPR)
DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL)
+ CALL_EXPR_LIST_INIT_P (in CALL_EXPR, AGGR_INIT_EXPR)
4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
or FIELD_DECL).
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
@@ -3026,6 +3029,10 @@ extern void decl_shadowed_for_var_insert (tree, tree);
should be performed at instantiation time. */
#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0 (CALL_EXPR_CHECK (NODE))
+/* True if CALL_EXPR expresses list-initialization of an object. */
+#define CALL_EXPR_LIST_INIT_P(NODE) \
+ TREE_LANG_FLAG_3 (TREE_CHECK2 ((NODE),CALL_EXPR,AGGR_INIT_EXPR))
+
/* Indicates whether a string literal has been parenthesized. Such
usages are disallowed in certain circumstances. */
@@ -3430,6 +3437,9 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
B b{1,2}, not B b({1,2}) or B b = {1,2}. */
#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE)))
+#define DIRECT_LIST_INIT_P(NODE) \
+ (BRACE_ENCLOSED_INITIALIZER_P (NODE) && CONSTRUCTOR_IS_DIRECT_INIT (NODE))
+
/* True if NODE represents a conversion for direct-initialization in a
template. Set by perform_implicit_conversion_flags. */
#define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \
@@ -4347,6 +4357,11 @@ extern int function_depth;
PARM_DECLs in cp_tree_equal. */
extern int comparing_specializations;
+/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
+ constants. */
+
+typedef int cp_cv_quals;
+
/* In parser.c. */
/* Nonzero if we are parsing an unevaluated operand: an operand to
@@ -4356,6 +4371,7 @@ extern int comparing_specializations;
extern int cp_unevaluated_operand;
extern tree cp_convert_range_for (tree, tree, tree, bool);
extern bool parsing_nsdmi (void);
+extern void inject_this_parameter (tree, cp_cv_quals);
/* in pt.c */
@@ -4735,11 +4751,6 @@ extern GTY(()) operator_name_info_t operator_name_info
extern GTY(()) operator_name_info_t assignment_operator_name_info
[(int) MAX_TREE_CODES];
-/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
- constants. */
-
-typedef int cp_cv_quals;
-
/* Non-static member functions have an optional virt-specifier-seq.
There is a VIRT_SPEC value for each virt-specifier.
They can be combined by bitwise-or to form the complete set of
@@ -5128,6 +5139,7 @@ extern void note_name_declared_in_class (tree, tree);
extern tree get_vtbl_decl_for_binfo (tree);
extern void debug_class (tree);
extern void debug_thunks (tree);
+extern tree cp_fold_obj_type_ref (tree, tree);
extern void set_linkage_according_to_type (tree, tree);
extern void determine_key_method (tree);
extern void check_for_override (tree, tree);
@@ -5315,6 +5327,10 @@ extern bool attributes_naming_typedef_ok (tree);
extern void cplus_decl_attributes (tree *, tree, int);
extern void finish_anon_union (tree);
extern void cp_write_global_declarations (void);
+extern void cp_process_pending_declarations (location_t);
+extern void cp_clear_deferred_fns (void);
+extern void cp_clear_constexpr_hashtable (void);
+extern void cp_clear_conv_type_map (void);
extern tree coerce_new_type (tree);
extern tree coerce_delete_type (tree);
extern void comdat_linkage (tree);
@@ -5415,6 +5431,7 @@ extern tree get_type_value (tree);
extern tree build_zero_init (tree, tree, bool);
extern tree build_value_init (tree, tsubst_flags_t);
extern tree build_value_init_noctor (tree, tsubst_flags_t);
+extern tree get_nsdmi (tree, bool);
extern tree build_offset_ref (tree, tree, bool,
tsubst_flags_t);
extern tree throw_bad_array_new_length (void);
@@ -5608,6 +5625,7 @@ extern tree get_template_argument_pack_elems (const_tree);
extern tree get_function_template_decl (const_tree);
extern tree resolve_nondeduced_context (tree);
extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
+extern void clear_pending_templates (void);
/* in repo.c */
extern void init_repo (void);
@@ -6151,6 +6169,7 @@ extern tree store_init_value (tree, tree, vec<tree, va_gc>**, int);
extern void check_narrowing (tree, tree);
extern tree digest_init (tree, tree, tsubst_flags_t);
extern tree digest_init_flags (tree, tree, int);
+extern tree digest_nsdmi_init (tree, tree);
extern tree build_scoped_ref (tree, tree, tree *);
extern tree build_x_arrow (location_t, tree,
tsubst_flags_t);
@@ -6175,6 +6194,7 @@ extern tree mangle_tls_init_fn (tree);
extern tree mangle_tls_wrapper_fn (tree);
extern bool decl_tls_wrapper_p (tree);
extern tree mangle_ref_init_variable (tree);
+extern void reset_temp_count (void);
extern char * get_mangled_vtable_map_var_name (tree);
/* in dump.c */
@@ -6191,6 +6211,22 @@ extern int cxx_types_compatible_p (tree, tree);
extern void init_shadowed_var_for_decl (void);
extern bool cxx_block_may_fallthru (const_tree);
+/* LIPO support. */
+extern bool cp_is_compiler_generated_type (tree);
+extern void cp_clear_global_name_bindings (tree);
+extern bool
+cp_is_non_sharable_global_decl (tree, void *);
+extern void cp_lipo_dup_lang_type (tree, tree);
+extern void cp_lipo_copy_lang_type (tree, tree);
+extern int cp_get_lang_decl_size (tree);
+extern int cp_cmp_lang_type (tree, tree);
+extern void cp_add_built_in_decl (tree);
+extern void cp_save_built_in_decl_pre_parsing (void);
+extern void cp_restore_built_in_decl_pre_parsing (void);
+extern void cp_save_built_in_decl_post_parsing (void);
+extern void cp_restore_built_in_decl_post_parsing (void);
+
+
/* in cp-gimplify.c */
extern int cp_gimplify_expr (tree *, gimple_seq *,
gimple_seq *);
@@ -6201,12 +6237,13 @@ extern tree cxx_omp_clause_default_ctor (tree, tree, tree);
extern tree cxx_omp_clause_copy_ctor (tree, tree, tree);
extern tree cxx_omp_clause_assign_op (tree, tree, tree);
extern tree cxx_omp_clause_dtor (tree, tree);
-extern void cxx_omp_finish_clause (tree);
+extern void cxx_omp_finish_clause (tree, gimple_seq *);
extern bool cxx_omp_privatize_by_reference (const_tree);
/* in name-lookup.c */
extern void suggest_alternatives_for (location_t, tree);
extern tree strip_using_decl (tree);
+extern void reset_anon_name (void);
/* in vtable-class-hierarchy.c */
extern void vtv_compute_class_hierarchy_transitive_closure (void);
diff --git a/gcc-4.9/gcc/cp/decl.c b/gcc-4.9/gcc/cp/decl.c
index 340059442..4dd0ec09f 100644
--- a/gcc-4.9/gcc/cp/decl.c
+++ b/gcc-4.9/gcc/cp/decl.c
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "pointer-set.h"
#include "splay-tree.h"
+#include "cgraph.h"
#include "plugin.h"
#include "cgraph.h"
#include "cilk.h"
@@ -561,6 +562,7 @@ poplevel (int keep, int reverse, int functionbody)
cp_label_binding *label_bind;
bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+
restart:
block = NULL_TREE;
@@ -870,7 +872,7 @@ walk_namespaces (walk_namespaces_fn f, void* data)
wrapup_global_declarations for this NAMESPACE. */
int
-wrapup_globals_for_namespace (tree name_space, void* data)
+wrapup_globals_for_namespace (tree name_space, void *data)
{
cp_binding_level *level = NAMESPACE_LEVEL (name_space);
vec<tree, va_gc> *statics = level->static_decls;
@@ -2467,7 +2469,26 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
/* The NEWDECL will no longer be needed. Because every out-of-class
declaration of a member results in a call to duplicate_decls,
freeing these nodes represents in a significant savings. */
- ggc_free (newdecl);
+ {
+ tree clone;
+ bool found_clone = false;
+ /* Fix dangling reference. */
+ FOR_EACH_CLONE (clone, newdecl)
+ {
+ if (DECL_CLONED_FUNCTION (clone) == newdecl)
+ {
+ found_clone = true;
+ break;
+ }
+ if (DECL_ABSTRACT_ORIGIN (clone) == newdecl)
+ {
+ found_clone = true;
+ break;
+ }
+ }
+ if (!found_clone)
+ ggc_free (newdecl);
+ }
return olddecl;
}
@@ -3696,6 +3717,7 @@ cxx_init_decl_processing (void)
{
tree void_ftype;
tree void_ftype_ptr;
+ tree void_ftype_ptr_sizetype;
/* Create all the identifiers we need. */
initialize_predefined_identifiers ();
@@ -3757,8 +3779,14 @@ cxx_init_decl_processing (void)
void_ftype = build_function_type_list (void_type_node, NULL_TREE);
void_ftype_ptr = build_function_type_list (void_type_node,
ptr_type_node, NULL_TREE);
+ void_ftype_ptr_sizetype = build_function_type_list (void_type_node,
+ ptr_type_node,
+ size_type_node,
+ NULL_TREE);
void_ftype_ptr
= build_exception_variant (void_ftype_ptr, empty_except_spec);
+ void_ftype_ptr_sizetype
+ = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec);
/* C++ extensions */
@@ -3809,7 +3837,7 @@ cxx_init_decl_processing (void)
{
tree newattrs, extvisattr;
- tree newtype, deltype;
+ tree newtype, deltype, deltype2;
tree ptr_ftype_sizetype;
tree new_eh_spec;
@@ -3847,10 +3875,12 @@ cxx_init_decl_processing (void)
newtype = build_exception_variant (newtype, new_eh_spec);
deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
+ deltype2 = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec);
DECL_IS_OPERATOR_NEW (push_cp_library_fn (NEW_EXPR, newtype, 0)) = 1;
DECL_IS_OPERATOR_NEW (push_cp_library_fn (VEC_NEW_EXPR, newtype, 0)) = 1;
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ push_cp_library_fn (DELETE_EXPR, deltype2, ECF_NOTHROW);
nullptr_type_node = make_node (NULLPTR_TYPE);
TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
@@ -5797,6 +5827,13 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
if (init && init != error_mark_node)
init_code = build2 (INIT_EXPR, type, decl, init);
+ if (init_code)
+ {
+ /* We might have set these in cp_finish_decl. */
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = false;
+ TREE_CONSTANT (decl) = false;
+ }
+
if (init_code && DECL_IN_AGGR_P (decl))
{
static int explained = 0;
@@ -5901,6 +5938,10 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
&& DECL_IMPLICIT_INSTANTIATION (decl))
defer_p = 1;
+ /* Capture the current module info. */
+ if (L_IPO_COMP_MODE)
+ varpool_node_for_decl (decl);
+
/* If we're not deferring, go ahead and assemble the variable. */
if (!defer_p)
rest_of_decl_compilation (decl, toplev, at_eof);
diff --git a/gcc-4.9/gcc/cp/decl2.c b/gcc-4.9/gcc/cp/decl2.c
index 6c52e53bc..3088918cd 100644
--- a/gcc-4.9/gcc/cp/decl2.c
+++ b/gcc-4.9/gcc/cp/decl2.c
@@ -103,9 +103,6 @@ static GTY(()) vec<tree, va_gc> *deferred_fns;
sure are defined. */
static GTY(()) vec<tree, va_gc> *no_linkage_decls;
-/* Nonzero if we're done parsing and into end-of-file activities. */
-
-int at_eof;
/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
@@ -3333,11 +3330,13 @@ start_static_storage_duration_function (unsigned count)
{
tree type;
tree body;
- char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32];
+ char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 64];
/* Create the identifier for this function. It will be of the form
SSDF_IDENTIFIER_<number>. */
sprintf (id, "%s_%u", SSDF_IDENTIFIER, count);
+ if (L_IPO_IS_AUXILIARY_MODULE)
+ sprintf (id, "%s.cmo.%u", id, current_module_id);
type = build_function_type_list (void_type_node,
integer_type_node, integer_type_node,
@@ -3772,6 +3771,9 @@ prune_vars_needing_no_initialization (tree *vars)
continue;
}
+ gcc_assert (!L_IPO_IS_AUXILIARY_MODULE
+ || varpool_is_auxiliary (varpool_node_for_decl (decl)));
+
/* This variable is going to need initialization and/or
finalization, so we add it to the list. */
*var = TREE_CHAIN (t);
@@ -4137,6 +4139,22 @@ no_linkage_error (tree decl)
"to declare function %q#D with linkage", t, decl);
}
+/* Clear the list of deferred functions. */
+
+void
+cp_clear_deferred_fns (void)
+{
+ vec_free (deferred_fns);
+ deferred_fns = NULL;
+ keyed_classes = NULL;
+ vec_free (no_linkage_decls);
+ no_linkage_decls = NULL;
+ cp_clear_constexpr_hashtable ();
+ clear_pending_templates ();
+ reset_anon_name ();
+ reset_temp_count ();
+}
+
/* Collect declarations from all namespaces relevant to SOURCE_FILE. */
static void
@@ -4237,69 +4255,16 @@ dump_tu (void)
first, since that way we only need to reverse the decls once. */
void
-cp_write_global_declarations (void)
+cp_process_pending_declarations (location_t locus)
{
- tree vars;
+ tree vars, decl;
bool reconsider;
size_t i;
- location_t locus;
unsigned ssdf_count = 0;
int retries = 0;
- tree decl;
- struct pointer_set_t *candidates;
-
- locus = input_location;
- at_eof = 1;
-
- /* Bad parse errors. Just forget about it. */
- if (! global_bindings_p () || current_class_type
- || !vec_safe_is_empty (decl_namespace_list))
- return;
-
- /* This is the point to write out a PCH if we're doing that.
- In that case we do not want to do anything else. */
- if (pch_file)
- {
- c_common_write_pch ();
- dump_tu ();
- return;
- }
-
- cgraph_process_same_body_aliases ();
-
- /* Handle -fdump-ada-spec[-slim] */
- if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
- {
- if (flag_dump_ada_spec_slim)
- collect_source_ref (main_input_filename);
- else
- collect_source_refs (global_namespace);
-
- dump_ada_specs (collect_all_refs, cpp_check);
- }
-
- /* FIXME - huh? was input_line -= 1;*/
timevar_start (TV_PHASE_DEFERRED);
- /* We now have to write out all the stuff we put off writing out.
- These include:
-
- o Template specializations that we have not yet instantiated,
- but which are needed.
- o Initialization and destruction for non-local objects with
- static storage duration. (Local objects with static storage
- duration are initialized when their scope is first entered,
- and are cleaned up via atexit.)
- o Virtual function tables.
-
- All of these may cause others to be needed. For example,
- instantiating one function may cause another to be needed, and
- generating the initializer for an object may cause templates to be
- instantiated, etc., etc. */
-
- emit_support_tinfos ();
-
do
{
tree t;
@@ -4535,6 +4500,26 @@ cp_write_global_declarations (void)
}
while (reconsider);
+ if (L_IPO_IS_AUXILIARY_MODULE)
+ {
+ tree fndecl;
+ int i;
+
+ gcc_assert (flag_dyn_ipa && L_IPO_COMP_MODE);
+
+ /* Do some cleanup -- we do not really need static init function
+ to be created for auxiliary modules -- they are created to keep
+ funcdef_no consistent between profile use and profile gen. */
+ FOR_EACH_VEC_SAFE_ELT (ssdf_decls, i, fndecl)
+ /* Such ssdf_decls are not called from GLOBAL ctor/dtor, mark
+ them reachable to avoid being eliminated too early before
+ gimplication. */
+ cgraph_enqueue_node (cgraph_get_create_node (fndecl));
+ ssdf_decls = NULL;
+ timevar_stop (TV_PHASE_DEFERRED);
+ return;
+ }
+
/* All used inline functions must have a definition at this point. */
FOR_EACH_VEC_SAFE_ELT (deferred_fns, i, decl)
{
@@ -4586,7 +4571,10 @@ cp_write_global_declarations (void)
/* We're done with the splay-tree now. */
if (priority_info_map)
- splay_tree_delete (priority_info_map);
+ {
+ splay_tree_delete (priority_info_map);
+ priority_info_map = NULL;
+ }
/* Generate any missing aliases. */
maybe_apply_pending_pragma_weaks ();
@@ -4595,10 +4583,76 @@ cp_write_global_declarations (void)
linkage now. */
pop_lang_context ();
+ ssdf_decls = NULL;
+ timevar_stop (TV_PHASE_DEFERRED);
+}
+
+/* This routine is called at the end of compilation.
+ Its job is to create all the code needed to initialize and
+ destroy the global aggregates. We do the destruction
+ first, since that way we only need to reverse the decls once. */
+
+void
+cp_write_global_declarations (void)
+{
+ bool reconsider = false;
+ location_t locus;
+ struct pointer_set_t *candidates;
+
+ locus = input_location;
+ at_eof = 1;
+
+ /* Bad parse errors. Just forget about it. */
+ if (! global_bindings_p () || current_class_type
+ || !vec_safe_is_empty (decl_namespace_list))
+ return;
+
+ if (pch_file)
+ {
+ c_common_write_pch ();
+ return;
+ }
+
+ cgraph_process_same_body_aliases ();
+
+ /* Handle -fdump-ada-spec[-slim] */
+ if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
+ {
+ if (flag_dump_ada_spec_slim)
+ collect_source_ref (main_input_filename);
+ else
+ collect_source_refs (global_namespace);
+
+ dump_ada_specs (collect_all_refs, cpp_check);
+ }
+
+ /* FIXME - huh? was input_line -= 1;*/
+
+ /* We now have to write out all the stuff we put off writing out.
+ These include:
+
+ o Template specializations that we have not yet instantiated,
+ but which are needed.
+ o Initialization and destruction for non-local objects with
+ static storage duration. (Local objects with static storage
+ duration are initialized when their scope is first entered,
+ and are cleaned up via atexit.)
+ o Virtual function tables.
+
+ All of these may cause others to be needed. For example,
+ instantiating one function may cause another to be needed, and
+ generating the initializer for an object may cause templates to be
+ instantiated, etc., etc. */
+
+ emit_support_tinfos ();
+
+ if (!L_IPO_COMP_MODE)
+ cp_process_pending_declarations (locus);
+
/* Collect candidates for Java hidden aliases. */
candidates = collect_candidates_for_java_method_aliases ();
- timevar_stop (TV_PHASE_DEFERRED);
+
timevar_start (TV_PHASE_OPT_GEN);
if (flag_vtable_verify)
diff --git a/gcc-4.9/gcc/cp/error.c b/gcc-4.9/gcc/cp/error.c
index 699d5458a..87ca4e2a3 100644
--- a/gcc-4.9/gcc/cp/error.c
+++ b/gcc-4.9/gcc/cp/error.c
@@ -318,6 +318,11 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
if (vec_safe_is_empty (typenames) || uses_template_parms (args))
return;
+ /* Don't try to print typenames when we're processing a clone. */
+ if (current_function_decl
+ && !DECL_LANG_SPECIFIC (current_function_decl))
+ return;
+
FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
{
if (need_semicolon)
diff --git a/gcc-4.9/gcc/cp/friend.c b/gcc-4.9/gcc/cp/friend.c
index 150b392b6..78c02df0e 100644
--- a/gcc-4.9/gcc/cp/friend.c
+++ b/gcc-4.9/gcc/cp/friend.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
+#include "cgraph.h"
/* Friend data structures are described in cp-tree.h. */
@@ -148,7 +149,8 @@ add_friend (tree type, tree decl, bool complain)
if (decl == TREE_VALUE (friends))
{
if (complain)
- warning (0, "%qD is already a friend of class %qT",
+ warning (OPT_Wredundant_decls,
+ "%qD is already a friend of class %qT",
decl, type);
return;
}
@@ -376,7 +378,8 @@ make_friend_class (tree type, tree friend_type, bool complain)
if (friend_type == probe)
{
if (complain)
- warning (0, "%qD is already a friend of %qT", probe, type);
+ warning (OPT_Wredundant_decls,
+ "%qD is already a friend of %qT", probe, type);
break;
}
}
@@ -385,7 +388,8 @@ make_friend_class (tree type, tree friend_type, bool complain)
if (same_type_p (probe, friend_type))
{
if (complain)
- warning (0, "%qT is already a friend of %qT", probe, type);
+ warning (OPT_Wredundant_decls,
+ "%qT is already a friend of %qT", probe, type);
break;
}
}
diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c
index 4373963a2..ecb103a99 100644
--- a/gcc-4.9/gcc/cp/init.c
+++ b/gcc-4.9/gcc/cp/init.c
@@ -522,6 +522,49 @@ perform_target_ctor (tree init)
}
}
+/* Return the non-static data initializer for FIELD_DECL MEMBER. */
+
+tree
+get_nsdmi (tree member, bool in_ctor)
+{
+ tree init;
+ tree save_ccp = current_class_ptr;
+ tree save_ccr = current_class_ref;
+ if (!in_ctor)
+ inject_this_parameter (DECL_CONTEXT (member), TYPE_UNQUALIFIED);
+ if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
+ {
+ /* Do deferred instantiation of the NSDMI. */
+ init = (tsubst_copy_and_build
+ (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
+ DECL_TI_ARGS (member),
+ tf_warning_or_error, member, /*function_p=*/false,
+ /*integral_constant_expression_p=*/false));
+
+ init = digest_nsdmi_init (member, init);
+ }
+ else
+ {
+ init = DECL_INITIAL (member);
+ if (init && TREE_CODE (init) == DEFAULT_ARG)
+ {
+ error ("constructor required before non-static data member "
+ "for %qD has been parsed", member);
+ DECL_INITIAL (member) = error_mark_node;
+ init = NULL_TREE;
+ }
+ /* Strip redundant TARGET_EXPR so we don't need to remap it, and
+ so the aggregate init code below will see a CONSTRUCTOR. */
+ if (init && TREE_CODE (init) == TARGET_EXPR
+ && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
+ init = TARGET_EXPR_INITIAL (init);
+ init = break_out_target_exprs (init);
+ }
+ current_class_ptr = save_ccp;
+ current_class_ref = save_ccr;
+ return init;
+}
+
/* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
arguments. If TREE_LIST is void_type_node, an empty initializer
list was given; if NULL_TREE no initializer was given. */
@@ -535,31 +578,7 @@ perform_member_init (tree member, tree init)
/* Use the non-static data member initializer if there was no
mem-initializer for this field. */
if (init == NULL_TREE)
- {
- if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
- /* Do deferred instantiation of the NSDMI. */
- init = (tsubst_copy_and_build
- (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
- DECL_TI_ARGS (member),
- tf_warning_or_error, member, /*function_p=*/false,
- /*integral_constant_expression_p=*/false));
- else
- {
- init = DECL_INITIAL (member);
- if (init && TREE_CODE (init) == DEFAULT_ARG)
- {
- error ("constructor required before non-static data member "
- "for %qD has been parsed", member);
- init = NULL_TREE;
- }
- /* Strip redundant TARGET_EXPR so we don't need to remap it, and
- so the aggregate init code below will see a CONSTRUCTOR. */
- if (init && TREE_CODE (init) == TARGET_EXPR
- && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
- init = TARGET_EXPR_INITIAL (init);
- init = break_out_target_exprs (init);
- }
- }
+ init = get_nsdmi (member, /*ctor*/true);
if (init == error_mark_node)
return;
@@ -744,8 +763,8 @@ perform_member_init (tree member, tree init)
tf_warning_or_error);
if (init)
- finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
- tf_warning_or_error));
+ finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
+ tf_warning_or_error));
}
if (type_build_dtor_call (type))
@@ -764,6 +783,11 @@ perform_member_init (tree member, tree init)
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
finish_eh_cleanup (expr);
}
+
+ /* Check for and warn about self-initialization if -Wself-assign is
+ enabled. */
+ if (warn_self_assign)
+ check_for_self_assign (input_location, decl, init);
}
/* Returns a TREE_LIST containing (as the TREE_PURPOSE of each node) all
@@ -2562,9 +2586,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
}
/* Perform the overflow check. */
tree errval = TYPE_MAX_VALUE (sizetype);
- /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length
- call. */
- if (cxx_dialect >= cxx11 && flag_exceptions && 0)
+ if (cxx_dialect >= cxx11 && flag_exceptions
+ /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length
+ call. */
+ && !TARGET_ANDROID)
errval = throw_bad_array_new_length ();
if (outer_nelts_check != NULL_TREE)
size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
diff --git a/gcc-4.9/gcc/cp/mangle.c b/gcc-4.9/gcc/cp/mangle.c
index da82dd6ac..169f84451 100644
--- a/gcc-4.9/gcc/cp/mangle.c
+++ b/gcc-4.9/gcc/cp/mangle.c
@@ -752,6 +752,10 @@ decl_mangling_context (tree decl)
if (tcontext != NULL_TREE)
return tcontext;
+ if (TREE_CODE (decl) == TEMPLATE_DECL
+ && DECL_TEMPLATE_RESULT (decl))
+ decl = DECL_TEMPLATE_RESULT (decl);
+
if (TREE_CODE (decl) == TYPE_DECL
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
{
@@ -3507,10 +3511,15 @@ mangle_decl (const tree decl)
tree id2, alias;
#endif
- SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
- if (IDENTIFIER_GLOBAL_VALUE (id) != decl)
- inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) "
- "avoids this error with a change in mangling");
+ if (!L_IPO_COMP_MODE || !is_parsing_done_p ())
+ SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
+ if (L_IPO_COMP_MODE && !is_parsing_done_p ())
+ add_decl_to_current_module_scope (decl,
+ NAMESPACE_LEVEL (global_namespace));
+ if (!L_IPO_COMP_MODE || !is_parsing_done_p ())
+ if (IDENTIFIER_GLOBAL_VALUE (id) != decl)
+ inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) "
+ "avoids this error with a change in mangling");
#ifdef ASM_OUTPUT_DEF
save_ver = flag_abi_version;
@@ -3786,6 +3795,14 @@ mangle_conv_op_name_for_type (const tree type)
return identifier;
}
+/* Clear the conversion map. */
+
+void
+cp_clear_conv_type_map (void)
+{
+ conv_type_names = NULL;
+}
+
/* Write out the appropriate string for this variable when generating
another mangled name based on this one. */
@@ -3857,6 +3874,14 @@ decl_tls_wrapper_p (const tree fn)
static GTY(()) int temp_count;
+/* Reset static variable temp_count to 0. */
+
+void
+reset_temp_count (void)
+{
+ temp_count = 0;
+}
+
tree
mangle_ref_init_variable (const tree variable)
{
diff --git a/gcc-4.9/gcc/cp/method.c b/gcc-4.9/gcc/cp/method.c
index 11bff7f45..5365b669c 100644
--- a/gcc-4.9/gcc/cp/method.c
+++ b/gcc-4.9/gcc/cp/method.c
@@ -362,8 +362,10 @@ use_thunk (tree thunk_fndecl, bool emit_p)
{
resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
- /* Output the thunk into the same section as function. */
- DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
+ /* Output the thunk into the same section as function if function reordering
+ is not switched on. */
+ if (!flag_reorder_functions)
+ DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
}
}
diff --git a/gcc-4.9/gcc/cp/name-lookup.c b/gcc-4.9/gcc/cp/name-lookup.c
index 0137c3f4a..ad8b4eb8b 100644
--- a/gcc-4.9/gcc/cp/name-lookup.c
+++ b/gcc-4.9/gcc/cp/name-lookup.c
@@ -634,6 +634,10 @@ add_decl_to_level (tree decl, cp_binding_level *b)
|| DECL_DECLARED_INLINE_P (decl))))
vec_safe_push (b->static_decls, decl);
}
+
+ /* The following call is needed for LIPO mode. In this mode, global
+ scope declarations are tracked on a per-module basis. */
+ add_decl_to_current_module_scope (decl, b);
}
/* Record a decl-node X as belonging to the current lexical scope.
@@ -1195,30 +1199,49 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
nowarn = true;
}
- if (warn_shadow && !nowarn)
+ if ((warn_shadow
+ || warn_shadow_local
+ || warn_shadow_compatible_local)
+ && !nowarn)
{
- bool warned;
-
+ enum opt_code warning_code;
+ /* If '-Wshadow-compatible-local' is specified without other
+ -Wshadow flags, we will warn only when the type of the
+ shadowing variable (i.e. x) can be converted to that of
+ the shadowed parameter (oldlocal). The reason why we only
+ check if x's type can be converted to oldlocal's type
+ (but not the other way around) is because when users
+ accidentally shadow a parameter, more than often they
+ would use the variable thinking (mistakenly) it's still
+ the parameter. It would be rare that users would use the
+ variable in the place that expects the parameter but
+ thinking it's a new decl. */
+ if (can_convert (TREE_TYPE (oldlocal), TREE_TYPE (x),
+ tf_none))
+ warning_code = OPT_Wshadow_compatible_local;
+ else
+ warning_code = OPT_Wshadow_local;
if (TREE_CODE (oldlocal) == PARM_DECL)
- warned = warning_at (input_location, OPT_Wshadow,
+ warning_at (input_location, warning_code,
"declaration of %q#D shadows a parameter", x);
else if (is_capture_proxy (oldlocal))
- warned = warning_at (input_location, OPT_Wshadow,
+ warning_at (input_location, warning_code,
"declaration of %qD shadows a lambda capture",
x);
else
- warned = warning_at (input_location, OPT_Wshadow,
+ warning_at (input_location, warning_code,
"declaration of %qD shadows a previous local",
x);
-
- if (warned)
- inform (DECL_SOURCE_LOCATION (oldlocal),
- "shadowed declaration is here");
+ warning_at (DECL_SOURCE_LOCATION (oldlocal), warning_code,
+ "shadowed declaration is here");
}
}
/* Maybe warn if shadowing something else. */
- else if (warn_shadow && !DECL_EXTERNAL (x)
+ else if ((warn_shadow
+ || warn_shadow_local
+ || warn_shadow_compatible_local)
+ && !DECL_EXTERNAL (x)
/* No shadow warnings for internally generated vars unless
it's an implicit typedef (see create_implicit_typedef
in decl.c). */
@@ -2068,6 +2091,14 @@ constructor_name_p (tree name, tree type)
static GTY(()) int anon_cnt;
+/* Reset static variable anon_cnt to 0. */
+
+void
+reset_anon_name (void)
+{
+ anon_cnt = 0;
+}
+
/* Return an IDENTIFIER which can be used as a name for
anonymous structs and unions. */
@@ -5080,7 +5111,6 @@ lookup_name_innermost_nonclass_level (tree name)
return ret;
}
-
/* Returns true iff DECL is a block-scope extern declaration of a function
or variable. */
diff --git a/gcc-4.9/gcc/cp/name-lookup.h b/gcc-4.9/gcc/cp/name-lookup.h
index 40e0338ca..cd29a0f5c 100644
--- a/gcc-4.9/gcc/cp/name-lookup.h
+++ b/gcc-4.9/gcc/cp/name-lookup.h
@@ -89,6 +89,7 @@ typedef struct GTY(()) cxx_saved_binding {
extern tree identifier_type_value (tree);
extern void set_identifier_type_value (tree, tree);
extern void pop_binding (tree, tree);
+extern void pop_global_binding (tree, cxx_binding*);
extern void pop_bindings_and_leave_scope (void);
extern tree constructor_name (tree);
extern bool constructor_name_p (tree, tree);
diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c
index aa00a7b68..706f6c020 100644
--- a/gcc-4.9/gcc/cp/parser.c
+++ b/gcc-4.9/gcc/cp/parser.c
@@ -1891,7 +1891,7 @@ static tree cp_parser_string_literal
static tree cp_parser_userdef_char_literal
(cp_parser *);
static tree cp_parser_userdef_string_literal
- (cp_token *);
+ (tree);
static tree cp_parser_userdef_numeric_literal
(cp_parser *);
@@ -3696,8 +3696,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
{
tree literal = build_userdef_literal (suffix_id, value,
OT_NONE, NULL_TREE);
- tok->u.value = literal;
- return cp_parser_userdef_string_literal (tok);
+ value = cp_parser_userdef_string_literal (literal);
}
}
else
@@ -3945,9 +3944,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
as arguments. */
static tree
-cp_parser_userdef_string_literal (cp_token *token)
+cp_parser_userdef_string_literal (tree literal)
{
- tree literal = token->u.value;
tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
tree value = USERDEF_LITERAL_VALUE (literal);
@@ -5835,20 +5833,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
}
break;
}
-
- case RID_CILK_SYNC:
- if (flag_cilkplus)
- {
- tree sync_expr = build_cilk_sync ();
- SET_EXPR_LOCATION (sync_expr,
- cp_lexer_peek_token (parser->lexer)->location);
- finish_expr_stmt (sync_expr);
- }
- else
- error_at (token->location, "-fcilkplus must be enabled to use"
- " %<_Cilk_sync%>");
- cp_lexer_consume_token (parser->lexer);
- break;
case RID_BUILTIN_SHUFFLE:
{
@@ -8099,6 +8083,16 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
tf_warning_or_error);
}
+/* A helpfer function to check if the given expression (EXPR) is of POD type.
+ Note that if the expression's type is NULL (e.g. when its type depends on
+ template parameters), we return false. */
+
+static bool
+expr_is_pod (tree expr)
+{
+ return TREE_TYPE (expr) && pod_type_p (TREE_TYPE (expr));
+}
+
/* Parse an assignment-expression.
assignment-expression:
@@ -8157,6 +8151,16 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
if (cp_parser_non_integral_constant_expression (parser,
NIC_ASSIGNMENT))
return error_mark_node;
+
+ /* Check for and warn about self-assignment if -Wself-assign is
+ enabled and the assignment operator is "=".
+ Checking for non-POD self-assignment will be performed only
+ when -Wself-assign-non-pod is enabled. */
+ if (warn_self_assign
+ && assignment_operator == NOP_EXPR
+ && (warn_self_assign_non_pod || expr_is_pod (expr)))
+ check_for_self_assign (input_location, expr, rhs);
+
/* Build the assignment expression. Its default
location is the location of the '=' token. */
saved_input_location = input_location;
@@ -9400,6 +9404,24 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
statement = cp_parser_jump_statement (parser);
break;
+ case RID_CILK_SYNC:
+ cp_lexer_consume_token (parser->lexer);
+ if (flag_cilkplus)
+ {
+ tree sync_expr = build_cilk_sync ();
+ SET_EXPR_LOCATION (sync_expr,
+ token->location);
+ statement = finish_expr_stmt (sync_expr);
+ }
+ else
+ {
+ error_at (token->location, "-fcilkplus must be enabled to use"
+ " %<_Cilk_sync%>");
+ statement = error_mark_node;
+ }
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ break;
+
/* Objective-C++ exception-handling constructs. */
case RID_AT_TRY:
case RID_AT_CATCH:
@@ -12866,6 +12888,9 @@ cp_parser_operator (cp_parser* parser)
static void
cp_parser_template_declaration (cp_parser* parser, bool member_p)
{
+ /* A hack to disable -Wself-assign warning in template parsing. */
+ int old_warn_self_assign = warn_self_assign;
+ warn_self_assign = 0;
/* Check for `export'. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT))
{
@@ -12876,6 +12901,7 @@ cp_parser_template_declaration (cp_parser* parser, bool member_p)
}
cp_parser_template_declaration_after_export (parser, member_p);
+ warn_self_assign = old_warn_self_assign;
}
/* Parse a template-parameter-list.
@@ -15045,6 +15071,18 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
return cp_parser_make_typename_type (parser, parser->scope,
identifier,
token->location);
+
+ /* Template parameter lists apply only if we are not within a
+ function parameter list. */
+ bool template_parm_lists_apply
+ = parser->num_template_parameter_lists;
+ if (template_parm_lists_apply)
+ for (cp_binding_level *s = current_binding_level;
+ s && s->kind != sk_template_parms;
+ s = s->level_chain)
+ if (s->kind == sk_function_parms)
+ template_parm_lists_apply = false;
+
/* Look up a qualified name in the usual way. */
if (parser->scope)
{
@@ -15087,7 +15125,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
decl = (cp_parser_maybe_treat_template_as_class
(decl, /*tag_name_p=*/is_friend
- && parser->num_template_parameter_lists));
+ && template_parm_lists_apply));
if (TREE_CODE (decl) != TYPE_DECL)
{
@@ -15100,9 +15138,9 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
{
- bool allow_template = (parser->num_template_parameter_lists
- || DECL_SELF_REFERENCE_P (decl));
- type = check_elaborated_type_specifier (tag_type, decl,
+ bool allow_template = (template_parm_lists_apply
+ || DECL_SELF_REFERENCE_P (decl));
+ type = check_elaborated_type_specifier (tag_type, decl,
allow_template);
if (type == error_mark_node)
@@ -15188,15 +15226,16 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
ts = ts_global;
template_p =
- (parser->num_template_parameter_lists
+ (template_parm_lists_apply
&& (cp_parser_next_token_starts_class_definition_p (parser)
|| cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)));
/* An unqualified name was used to reference this type, so
there were no qualifying templates. */
- if (!cp_parser_check_template_parameters (parser,
- /*num_templates=*/0,
- token->location,
- /*declarator=*/NULL))
+ if (template_parm_lists_apply
+ && !cp_parser_check_template_parameters (parser,
+ /*num_templates=*/0,
+ token->location,
+ /*declarator=*/NULL))
return error_mark_node;
type = xref_tag (tag_type, identifier, ts, template_p);
}
@@ -16096,7 +16135,6 @@ cp_parser_alias_declaration (cp_parser* parser)
id = cp_parser_identifier (parser);
if (id == error_mark_node)
return error_mark_node;
-
cp_token *attrs_token = cp_lexer_peek_token (parser->lexer);
attributes = cp_parser_attributes_opt (parser);
if (attributes == error_mark_node)
@@ -16869,6 +16907,10 @@ cp_parser_init_declarator (cp_parser* parser,
`explicit' constructor cannot be used. */
((is_direct_init || !is_initialized)
? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
+ /* Check for and warn about self-initialization if -Wself-assign is
+ enabled. */
+ if (warn_self_assign && initializer)
+ check_for_self_assign (input_location, decl, initializer);
}
else if ((cxx_dialect != cxx98) && friend_p
&& decl && TREE_CODE (decl) == FUNCTION_DECL)
@@ -17837,7 +17879,7 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser)
/* Used by handling of trailing-return-types and NSDMI, in which 'this'
is in scope even though it isn't real. */
-static void
+void
inject_this_parameter (tree ctype, cp_cv_quals quals)
{
tree this_parm;
@@ -23090,10 +23132,17 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
ok = false;
}
if (!ok)
- error ("literal operator template %qD has invalid parameter list."
- " Expected non-type template argument pack <char...>"
- " or <typename CharT, CharT...>",
- decl);
+ {
+ if (cxx_dialect >= cxx1y)
+ error ("literal operator template %qD has invalid parameter list."
+ " Expected non-type template argument pack <char...>"
+ " or <typename CharT, CharT...>",
+ decl);
+ else
+ error ("literal operator template %qD has invalid parameter list."
+ " Expected non-type template argument pack <char...>",
+ decl);
+ }
}
/* Register member declarations. */
if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
@@ -23664,16 +23713,7 @@ cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
parsed_arg = check_default_argument (parmtype, parsed_arg,
tf_warning_or_error);
else
- {
- int flags = LOOKUP_IMPLICIT;
- if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg)
- && CONSTRUCTOR_IS_DIRECT_INIT (parsed_arg))
- flags = LOOKUP_NORMAL;
- parsed_arg = digest_init_flags (TREE_TYPE (decl), parsed_arg, flags);
- if (TREE_CODE (parsed_arg) == TARGET_EXPR)
- /* This represents the whole initialization. */
- TARGET_EXPR_DIRECT_INIT_P (parsed_arg) = true;
- }
+ parsed_arg = digest_nsdmi_init (decl, parsed_arg);
}
/* If the token stream has not been completely used up, then
@@ -29361,9 +29401,17 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
change it to shared (decl) in OMP_PARALLEL_CLAUSES. */
tree l = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
OMP_CLAUSE_DECL (l) = real_decl;
- OMP_CLAUSE_CHAIN (l) = clauses;
CP_OMP_CLAUSE_INFO (l) = CP_OMP_CLAUSE_INFO (*c);
- clauses = l;
+ if (code == OMP_SIMD)
+ {
+ OMP_CLAUSE_CHAIN (l) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
+ cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
+ }
+ else
+ {
+ OMP_CLAUSE_CHAIN (l) = clauses;
+ clauses = l;
+ }
OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
CP_OMP_CLAUSE_INFO (*c) = NULL;
add_private_clause = false;
@@ -31667,14 +31715,6 @@ pragma_lex (tree *value)
void
c_parse_file (void)
{
- static bool already_called = false;
-
- if (already_called)
- {
- sorry ("inter-module optimizations not implemented for C++");
- return;
- }
- already_called = true;
the_parser = cp_parser_new ();
push_deferring_access_checks (flag_access_control
diff --git a/gcc-4.9/gcc/cp/parser.h b/gcc-4.9/gcc/cp/parser.h
index d558c607f..628d1ae65 100644
--- a/gcc-4.9/gcc/cp/parser.h
+++ b/gcc-4.9/gcc/cp/parser.h
@@ -350,6 +350,15 @@ typedef struct GTY(()) cp_parser {
outermost class being defined is complete. */
vec<cp_unparsed_functions_entry, va_gc> *unparsed_queues;
+ /* A list of attributes whose arguments are not yet parsed. The
+ TREE_VALUE of each list node contains a delayed attribute.
+ The argument of the attribute (i.e. TREE_VALUE of the attribute)
+ is a special tree list node, where the TREE_PURPOSE is error_mark_node
+ and the TREE_VALUE points to the cached tokens of the arguments.
+ This list is processed once the outermost class being defined is
+ complete. */
+ tree unparsed_attribute_args_queue;
+
/* The number of classes whose definitions are currently in
progress. */
unsigned num_classes_being_defined;
diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c
index 3951997b0..54676afcc 100644
--- a/gcc-4.9/gcc/cp/pt.c
+++ b/gcc-4.9/gcc/cp/pt.c
@@ -43,8 +43,10 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "decl.h"
#include "toplev.h"
+#include "opts.h"
#include "timevar.h"
#include "tree-iterator.h"
+#include "cgraph.h"
#include "type-utils.h"
#include "gimplify.h"
@@ -63,6 +65,13 @@ struct GTY ((chain_next ("%h.next"))) pending_template {
static GTY(()) struct pending_template *pending_templates;
static GTY(()) struct pending_template *last_pending_template;
+void
+clear_pending_templates (void)
+{
+ pending_templates = NULL;
+ last_pending_template = NULL;
+}
+
int processing_template_parmlist;
static int template_header_count;
@@ -4423,7 +4432,8 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
in the template-parameter-list of the definition of a member of a
class template. */
- if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL)
+ if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL
+ || (TREE_CODE (decl) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_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. */
@@ -5345,6 +5355,10 @@ check_valid_ptrmem_cst_expr (tree type, tree expr,
return true;
if (cxx_dialect >= cxx11 && null_member_pointer_value_p (expr))
return true;
+ if (processing_template_decl
+ && TREE_CODE (expr) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 0)) == OFFSET_REF)
+ return true;
if (complain & tf_error)
{
error ("%qE is not a valid template argument for type %qT",
@@ -14189,11 +14203,7 @@ tsubst_copy_and_build (tree t,
if (error_msg)
error (error_msg);
if (!function_p && identifier_p (decl))
- {
- if (complain & tf_error)
- unqualified_name_lookup_error (decl);
- decl = error_mark_node;
- }
+ decl = unqualified_name_lookup_error (decl);
RETURN (decl);
}
@@ -15636,7 +15646,7 @@ pack_deducible_p (tree parm, tree fn)
continue;
for (packs = PACK_EXPANSION_PARAMETER_PACKS (type);
packs; packs = TREE_CHAIN (packs))
- if (TREE_VALUE (packs) == parm)
+ if (template_args_equal (TREE_VALUE (packs), parm))
{
/* The template parameter pack is used in a function parameter
pack. If this is the end of the parameter list, the
@@ -16360,8 +16370,9 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
maybe_adjust_types_for_deduction (strict, &parm, &arg, arg_expr);
}
else
- gcc_assert ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL)
- == (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL));
+ if ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL)
+ != (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL))
+ return unify_template_argument_mismatch (explain_p, parm, arg);
/* For deduction from an init-list we need the actual list. */
if (arg_expr && BRACE_ENCLOSED_INITIALIZER_P (arg_expr))
@@ -16697,7 +16708,16 @@ resolve_overloaded_unification (tree tparms,
int i = TREE_VEC_LENGTH (targs);
for (; i--; )
if (TREE_VEC_ELT (tempargs, i))
- TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (tempargs, i);
+ {
+ tree old = TREE_VEC_ELT (targs, i);
+ tree new_ = TREE_VEC_ELT (tempargs, i);
+ if (new_ && old && ARGUMENT_PACK_P (old)
+ && ARGUMENT_PACK_EXPLICIT_ARGS (old))
+ /* Don't forget explicit template arguments in a pack. */
+ ARGUMENT_PACK_EXPLICIT_ARGS (new_)
+ = ARGUMENT_PACK_EXPLICIT_ARGS (old);
+ TREE_VEC_ELT (targs, i) = new_;
+ }
}
if (good)
return true;
@@ -19766,7 +19786,13 @@ instantiate_decl (tree d, int defer_ok,
when marked as "extern template". */
if (!(external_p && VAR_P (d)))
add_pending_template (d);
- goto out;
+ {
+ if (L_IPO_COMP_MODE)
+ /* Capture module info. */
+ if (TREE_CODE (d) == VAR_DECL)
+ varpool_node_for_decl (d);
+ goto out;
+ }
}
/* Tell the repository that D is available in this translation unit
-- and see if it is supposed to be instantiated here. */
@@ -20936,7 +20962,12 @@ type_dependent_expression_p (tree expression)
return true;
if (BASELINK_P (expression))
- expression = BASELINK_FUNCTIONS (expression);
+ {
+ if (BASELINK_OPTYPE (expression)
+ && dependent_type_p (BASELINK_OPTYPE (expression)))
+ return true;
+ expression = BASELINK_FUNCTIONS (expression);
+ }
if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
{
diff --git a/gcc-4.9/gcc/cp/rtti.c b/gcc-4.9/gcc/cp/rtti.c
index a8e6d25c8..7600215de 100644
--- a/gcc-4.9/gcc/cp/rtti.c
+++ b/gcc-4.9/gcc/cp/rtti.c
@@ -1231,6 +1231,10 @@ create_pseudo_type_info (int tk, const char *real_name, ...)
/* Create the pseudo type. */
pseudo_type = make_class_type (RECORD_TYPE);
finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
+ /* For lightweight IPO (LIPO), the list of builtin decls
+ and types are remembered. */
+ cp_add_built_in_decl (pseudo_type);
+
CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
ti = &(*tinfo_descs)[tk];
@@ -1396,6 +1400,9 @@ create_tinfo_types (void)
ti->name = NULL_TREE;
finish_builtin_struct (ti->type, "__type_info_pseudo",
fields, NULL_TREE);
+ /* For lightweight IPO (LIPO), the list of builtin decls
+ and types are remembered. */
+ cp_add_built_in_decl (ti->type);
}
/* Fundamental type_info */
@@ -1437,6 +1444,9 @@ create_tinfo_types (void)
ti->name = NULL_TREE;
finish_builtin_struct (ti->type, "__base_class_type_info_pseudo",
fields, NULL_TREE);
+ /* For lightweight IPO (LIPO), the list of builtin decls
+ and types are remembered. */
+ cp_add_built_in_decl (ti->type);
}
/* Pointer type_info. Adds two fields, qualification mask
diff --git a/gcc-4.9/gcc/cp/semantics.c b/gcc-4.9/gcc/cp/semantics.c
index 3619e271d..de5e536f5 100644
--- a/gcc-4.9/gcc/cp/semantics.c
+++ b/gcc-4.9/gcc/cp/semantics.c
@@ -2600,7 +2600,6 @@ finish_compound_literal (tree type, tree compound_literal,
if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
&& TREE_CODE (type) == ARRAY_TYPE
&& !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
- && !cp_unevaluated_operand
&& initializer_constant_valid_p (compound_literal, type))
{
tree decl = create_temporary_var (type);
@@ -2621,10 +2620,16 @@ finish_compound_literal (tree type, tree compound_literal,
decl = pushdecl_top_level (decl);
DECL_NAME (decl) = make_anon_name ();
SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+
+ /* Capture the current module info for statics. */
+ if (L_IPO_COMP_MODE)
+ varpool_node_for_decl (decl);
+
/* Make sure the destructor is callable. */
tree clean = cxx_maybe_build_cleanup (decl, complain);
if (clean == error_mark_node)
return error_mark_node;
+
return decl;
}
else
@@ -3867,6 +3872,7 @@ simplify_aggr_init_expr (tree *tp)
aggr_init_expr_nargs (aggr_init_expr),
AGGR_INIT_EXPR_ARGP (aggr_init_expr));
TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
+ CALL_EXPR_LIST_INIT_P (call_expr) = CALL_EXPR_LIST_INIT_P (aggr_init_expr);
if (style == ctor)
{
@@ -3925,6 +3931,18 @@ emit_associated_thunks (tree fn)
{
tree thunk;
+ if (L_IPO_COMP_MODE)
+ {
+ /* In LIPO mode, multiple copies of definitions for the same function
+ may exist, but assembler hash table keeps only one copy which might
+ have been deleted at this point. */
+ struct cgraph_node *n = cgraph_get_create_node (fn);
+ #ifdef FIXME_LIPO
+ insert_to_assembler_name_hash ((symtab_node)n);
+ #endif
+ cgraph_link_node (n);
+ }
+
for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk))
{
if (!THUNK_ALIAS (thunk))
@@ -5283,6 +5301,8 @@ finish_omp_clauses (tree clauses)
break;
}
}
+ else
+ t = fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (c)), t);
}
OMP_CLAUSE_LINEAR_STEP (c) = t;
}
@@ -7964,6 +7984,15 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
return bad;
}
+/* Clear constexpr hash table */
+
+void
+cp_clear_constexpr_hashtable (void)
+{
+ /* htab_delete (constexpr_fundef_table); */
+ constexpr_fundef_table = NULL;
+}
+
/* We are processing the definition of the constexpr function FUN.
Check that its BODY fulfills the propriate requirements and
enter it in the constexpr function definition table.
@@ -8511,11 +8540,24 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t,
bool
reduced_constant_expression_p (tree t)
{
- if (TREE_CODE (t) == PTRMEM_CST)
- /* Even if we can't lower this yet, it's constant. */
- return true;
- /* FIXME are we calling this too much? */
- return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
+ switch (TREE_CODE (t))
+ {
+ case PTRMEM_CST:
+ /* Even if we can't lower this yet, it's constant. */
+ return true;
+
+ case CONSTRUCTOR:
+ /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
+ tree elt; unsigned HOST_WIDE_INT idx;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, elt)
+ if (!reduced_constant_expression_p (elt))
+ return false;
+ return true;
+
+ default:
+ /* FIXME are we calling this too much? */
+ return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
+ }
}
/* Some expressions may have constant operands but are not constant
diff --git a/gcc-4.9/gcc/cp/tree.c b/gcc-4.9/gcc/cp/tree.c
index 3429d2396..622ba99f7 100644
--- a/gcc-4.9/gcc/cp/tree.c
+++ b/gcc-4.9/gcc/cp/tree.c
@@ -101,6 +101,16 @@ lvalue_kind (const_tree ref)
case IMAGPART_EXPR:
return lvalue_kind (TREE_OPERAND (ref, 0));
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ if (TREE_CODE (ref) == MEMBER_REF)
+ op1_lvalue_kind = clk_ordinary;
+ else
+ op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+ if (TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
+ op1_lvalue_kind = clk_none;
+ return op1_lvalue_kind;
+
case COMPONENT_REF:
op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
/* Look at the member designator. */
@@ -453,6 +463,7 @@ build_aggr_init_expr (tree type, tree init)
TREE_SIDE_EFFECTS (rval) = 1;
AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
TREE_NOTHROW (rval) = TREE_NOTHROW (init);
+ CALL_EXPR_LIST_INIT_P (rval) = CALL_EXPR_LIST_INIT_P (init);
}
else
rval = init;
diff --git a/gcc-4.9/gcc/cp/typeck.c b/gcc-4.9/gcc/cp/typeck.c
index 9a80727dd..3c8d62fbc 100644
--- a/gcc-4.9/gcc/cp/typeck.c
+++ b/gcc-4.9/gcc/cp/typeck.c
@@ -1396,7 +1396,11 @@ comptypes (tree t1, tree t2, int strict)
{
bool result = structural_comptypes (t1, t2, strict);
- if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
+ if (result && (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2)
+ /* In LIPO mode, the builtin functions are shared across
+ different TUs. The parameter type of the builtin may
+ not be the same instance as the arg type. */
+ && !L_IPO_COMP_MODE))
/* The two types are structurally equivalent, but their
canonical types were different. This is a failure of the
canonical type propagation code.*/
diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c
index 85696f6e0..0bdad2a51 100644
--- a/gcc-4.9/gcc/cp/typeck2.c
+++ b/gcc-4.9/gcc/cp/typeck2.c
@@ -1097,6 +1097,22 @@ digest_init_flags (tree type, tree init, int flags)
{
return digest_init_r (type, init, false, flags, tf_warning_or_error);
}
+
+/* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL). */
+tree
+digest_nsdmi_init (tree decl, tree init)
+{
+ gcc_assert (TREE_CODE (decl) == FIELD_DECL);
+
+ int flags = LOOKUP_IMPLICIT;
+ if (DIRECT_LIST_INIT_P (init))
+ flags = LOOKUP_NORMAL;
+ init = digest_init_flags (TREE_TYPE (decl), init, flags);
+ if (TREE_CODE (init) == TARGET_EXPR)
+ /* This represents the whole initialization. */
+ TARGET_EXPR_DIRECT_INIT_P (init) = true;
+ return init;
+}
/* Set of flags used within process_init_constructor to describe the
initializers. */