summaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-27 10:13:12 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-27 10:13:12 +0000
commite0e4357b88efe5dc53e50d341a09de4d02331200 (patch)
treecafff2748190357bac05d69d344e79b0e38d1e27 /gcc/cp/decl2.c
parent7b48bf2011b4020c4a5a2d5d4149b03983f72cc2 (diff)
downloadgcc-tarball-e0e4357b88efe5dc53e50d341a09de4d02331200.tar.gz
gcc-6.1.0gcc-6.1.0
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c444
1 files changed, 250 insertions, 194 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8d895fef43..0ea326d769 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1,5 +1,5 @@
/* Process declarations and variables for C++ compiler.
- Copyright (C) 1988-2015 Free Software Foundation, Inc.
+ Copyright (C) 1988-2016 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
@@ -29,45 +29,22 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "vec.h"
-#include "double-int.h"
-#include "input.h"
-#include "alias.h"
-#include "symtab.h"
-#include "wide-int.h"
-#include "inchash.h"
-#include "tree.h"
+#include "target.h"
+#include "cp-tree.h"
+#include "c-family/c-common.h"
+#include "timevar.h"
#include "stringpool.h"
+#include "cgraph.h"
#include "varasm.h"
#include "attribs.h"
#include "stor-layout.h"
#include "calls.h"
-#include "flags.h"
-#include "cp-tree.h"
#include "decl.h"
#include "toplev.h"
-#include "timevar.h"
-#include "cpplib.h"
-#include "target.h"
-#include "c-family/c-common.h"
#include "c-family/c-objc.h"
-#include "hash-map.h"
-#include "is-a.h"
-#include "plugin-api.h"
-#include "hard-reg-set.h"
-#include "input.h"
-#include "function.h"
-#include "ipa-ref.h"
-#include "cgraph.h"
-#include "tree-inline.h"
#include "c-family/c-pragma.h"
#include "dumpfile.h"
#include "intl.h"
-#include "splay-tree.h"
-#include "langhooks.h"
#include "c-family/c-ada-spec.h"
#include "asan.h"
@@ -200,6 +177,8 @@ change_return_type (tree new_ret, tree fntype)
else
newtype = build_method_type_directly
(class_of_this_parm (fntype), new_ret, TREE_CHAIN (args));
+ if (FUNCTION_REF_QUALIFIED (fntype))
+ newtype = build_ref_qualified_type (newtype, type_memfn_rqual (fntype));
if (raises)
newtype = build_exception_variant (newtype, raises);
if (attrs)
@@ -375,6 +354,7 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp,
tree expr;
tree orig_array_expr = array_expr;
tree orig_index_exp = index_exp;
+ tree overload = NULL_TREE;
if (error_operand_p (array_expr) || error_operand_p (index_exp))
return error_mark_node;
@@ -400,7 +380,7 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp,
if (decltype_p)
complain |= tf_decltype;
expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr,
- index_exp, NULL_TREE, /*overload=*/NULL, complain);
+ index_exp, NULL_TREE, &overload, complain);
}
else
{
@@ -410,7 +390,7 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp,
It is a little-known fact that, if `a' is an array and `i' is
an int, you can write `i[a]', which means the same thing as
`a[i]'. */
- if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
+ if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type))
p1 = array_expr;
else
p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
@@ -445,8 +425,14 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp,
expr = build_array_ref (input_location, array_expr, index_exp);
}
if (processing_template_decl && expr != error_mark_node)
- return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
- NULL_TREE, NULL_TREE);
+ {
+ if (overload != NULL_TREE)
+ return (build_min_non_dep_op_overload
+ (ARRAY_REF, expr, overload, orig_array_expr, orig_index_exp));
+
+ return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
+ NULL_TREE, NULL_TREE);
+ }
return expr;
}
@@ -730,6 +716,10 @@ check_classfn (tree ctype, tree function, tree template_parms)
!= type_memfn_rqual (TREE_TYPE (fndecl)))
continue;
+ // Include constraints in the match.
+ tree c1 = get_constraints (function);
+ tree c2 = get_constraints (fndecl);
+
/* While finding a match, same types and params are not enough
if the function is versioned. Also check version ("target")
attributes. */
@@ -740,6 +730,7 @@ check_classfn (tree ctype, tree function, tree template_parms)
&& (!is_template
|| comp_template_parms (template_parms,
DECL_TEMPLATE_PARMS (fndecl)))
+ && equivalent_constraints (c1, c2)
&& (DECL_TEMPLATE_SPECIALIZATION (function)
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
@@ -1020,7 +1011,7 @@ grokfield (const cp_declarator *declarator,
return value;
/* Need to set this before push_template_decl. */
- if (TREE_CODE (value) == VAR_DECL)
+ if (VAR_P (value))
DECL_CONTEXT (value) = current_class_type;
if (processing_template_decl && VAR_OR_FUNCTION_DECL_P (value))
@@ -1179,6 +1170,10 @@ is_late_template_attribute (tree attr, tree decl)
if (is_attribute_p ("unused", name))
return false;
+ /* Attribute tls_model wants to modify the symtab. */
+ if (is_attribute_p ("tls_model", name))
+ return true;
+
/* #pragma omp declare simd attribute needs to be always deferred. */
if (flag_openmp
&& is_attribute_p ("omp declare simd", name))
@@ -1198,7 +1193,8 @@ is_late_template_attribute (tree attr, tree decl)
second and following arguments. Attributes like mode, format,
cleanup and several target specific attributes aren't late
just because they have an IDENTIFIER_NODE as first argument. */
- if (arg == args && identifier_p (t))
+ if (arg == args && attribute_takes_identifier_p (name)
+ && identifier_p (t))
continue;
if (value_dependent_expression_p (t)
@@ -1432,7 +1428,7 @@ cp_omp_mappable_type (tree type)
{
tree field;
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
- if (TREE_CODE (field) == VAR_DECL)
+ if (VAR_P (field))
return false;
/* All fields must have mappable types. */
else if (TREE_CODE (field) == FIELD_DECL
@@ -1453,21 +1449,16 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
/* Add implicit "omp declare target" attribute if requested. */
if (scope_chain->omp_declare_target_attribute
- && ((TREE_CODE (*decl) == VAR_DECL
+ && ((VAR_P (*decl)
&& (TREE_STATIC (*decl) || DECL_EXTERNAL (*decl)))
|| TREE_CODE (*decl) == FUNCTION_DECL))
{
- if (TREE_CODE (*decl) == VAR_DECL
+ if (VAR_P (*decl)
&& DECL_CLASS_SCOPE_P (*decl))
error ("%q+D static data member inside of declare target directive",
*decl);
- else if (TREE_CODE (*decl) == VAR_DECL
- && (DECL_FUNCTION_SCOPE_P (*decl)
- || (current_function_decl && !DECL_EXTERNAL (*decl))))
- error ("%q+D in block scope inside of declare target directive",
- *decl);
else if (!processing_template_decl
- && TREE_CODE (*decl) == VAR_DECL
+ && VAR_P (*decl)
&& !cp_omp_mappable_type (TREE_TYPE (*decl)))
error ("%q+D in declare target directive does not have mappable type",
*decl);
@@ -1543,15 +1534,18 @@ build_anon_union_vars (tree type, tree object)
continue;
if (TREE_CODE (field) != FIELD_DECL)
{
- permerror (input_location, "%q+#D invalid; an anonymous union can only "
+ permerror (DECL_SOURCE_LOCATION (field),
+ "%q#D invalid; an anonymous union can only "
"have non-static data members", field);
continue;
}
if (TREE_PRIVATE (field))
- permerror (input_location, "private member %q+#D in anonymous union", field);
+ permerror (DECL_SOURCE_LOCATION (field),
+ "private member %q#D in anonymous union", field);
else if (TREE_PROTECTED (field))
- permerror (input_location, "protected member %q+#D in anonymous union", field);
+ permerror (DECL_SOURCE_LOCATION (field),
+ "protected member %q#D in anonymous union", field);
if (processing_template_decl)
ref = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, object,
@@ -1827,7 +1821,8 @@ comdat_linkage (tree decl)
}
}
- DECL_COMDAT (decl) = 1;
+ if (TREE_PUBLIC (decl))
+ DECL_COMDAT (decl) = 1;
}
/* For win32 we also want to put explicit instantiations in
@@ -1877,15 +1872,19 @@ maybe_make_one_only (tree decl)
bool
vague_linkage_p (tree decl)
{
+ if (!TREE_PUBLIC (decl))
+ {
+ gcc_checking_assert (!DECL_COMDAT (decl));
+ return false;
+ }
/* Unfortunately, import_export_decl has not always been called
before the function is processed, so we cannot simply check
DECL_COMDAT. */
if (DECL_COMDAT (decl)
- || (((TREE_CODE (decl) == FUNCTION_DECL
- && DECL_DECLARED_INLINE_P (decl))
- || (DECL_LANG_SPECIFIC (decl)
- && DECL_TEMPLATE_INSTANTIATION (decl)))
- && TREE_PUBLIC (decl)))
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl))
+ || (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INSTANTIATION (decl)))
return true;
else if (DECL_FUNCTION_SCOPE_P (decl))
/* A local static in an inline effectively has vague linkage. */
@@ -1994,7 +1993,7 @@ mark_needed (tree decl)
FOR_EACH_CLONE (clone, decl)
mark_needed (clone);
}
- else if (TREE_CODE (decl) == VAR_DECL)
+ else if (VAR_P (decl))
{
varpool_node *node = varpool_node::get_create (decl);
/* C++ frontend use mark_decl_references to force COMDAT variables
@@ -2193,8 +2192,7 @@ constrain_visibility (tree decl, int visibility, bool tmpl)
DECL_WEAK (decl) = 0;
DECL_COMMON (decl) = 0;
DECL_COMDAT (decl) = false;
- if (TREE_CODE (decl) == FUNCTION_DECL
- || TREE_CODE (decl) == VAR_DECL)
+ if (VAR_OR_FUNCTION_DECL_P (decl))
{
struct symtab_node *snode = symtab_node::get (decl);
@@ -2402,9 +2400,7 @@ determine_visibility (tree decl)
{
/* If the specialization doesn't specify visibility, use the
visibility from the template. */
- tree tinfo = (TREE_CODE (decl) == TYPE_DECL
- ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
- : DECL_TEMPLATE_INFO (decl));
+ tree tinfo = get_template_info (decl);
tree args = TI_ARGS (tinfo);
tree attribs = (TREE_CODE (decl) == TYPE_DECL
? TYPE_ATTRIBUTES (TREE_TYPE (decl))
@@ -2567,10 +2563,25 @@ constrain_class_visibility (tree type)
if (subvis == VISIBILITY_ANON)
{
- if (!in_main_input_context ())
- warning (0, "\
+ if (!in_main_input_context())
+ {
+ tree nlt = no_linkage_check (ftype, /*relaxed_p=*/false);
+ if (nlt)
+ {
+ if (same_type_p (TREE_TYPE (t), nlt))
+ warning (OPT_Wsubobject_linkage, "\
+%qT has a field %qD whose type has no linkage",
+ type, t);
+ else
+ warning (OPT_Wsubobject_linkage, "\
+%qT has a field %qD whose type depends on the type %qT which has no linkage",
+ type, t, nlt);
+ }
+ else
+ warning (OPT_Wsubobject_linkage, "\
%qT has a field %qD whose type uses the anonymous namespace",
- type, t);
+ type, t);
+ }
}
else if (MAYBE_CLASS_TYPE_P (ftype)
&& vis < VISIBILITY_HIDDEN
@@ -2588,9 +2599,24 @@ constrain_class_visibility (tree type)
if (subvis == VISIBILITY_ANON)
{
if (!in_main_input_context())
- warning (0, "\
+ {
+ tree nlt = no_linkage_check (TREE_TYPE (t), /*relaxed_p=*/false);
+ if (nlt)
+ {
+ if (same_type_p (TREE_TYPE (t), nlt))
+ warning (OPT_Wsubobject_linkage, "\
+%qT has a base %qT whose type has no linkage",
+ type, TREE_TYPE (t));
+ else
+ warning (OPT_Wsubobject_linkage, "\
+%qT has a base %qT whose type depends on the type %qT which has no linkage",
+ type, TREE_TYPE (t), nlt);
+ }
+ else
+ warning (OPT_Wsubobject_linkage, "\
%qT has a base %qT whose type uses the anonymous namespace",
- type, TREE_TYPE (t));
+ type, TREE_TYPE (t));
+ }
}
else if (vis < VISIBILITY_HIDDEN
&& subvis >= VISIBILITY_HIDDEN)
@@ -2659,10 +2685,23 @@ reset_type_linkage_2 (tree type)
reset_decl_linkage (ti);
}
for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
- if (TREE_CODE (m) == VAR_DECL)
- reset_decl_linkage (m);
+ {
+ tree mem = STRIP_TEMPLATE (m);
+ if (VAR_P (mem))
+ reset_decl_linkage (mem);
+ }
for (tree m = TYPE_METHODS (type); m; m = DECL_CHAIN (m))
- reset_decl_linkage (m);
+ {
+ tree mem = STRIP_TEMPLATE (m);
+ reset_decl_linkage (mem);
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (mem))
+ {
+ /* Also update its name, for cxx_dwarf_name. */
+ DECL_NAME (mem) = TYPE_IDENTIFIER (type);
+ if (m != mem)
+ DECL_NAME (m) = TYPE_IDENTIFIER (type);
+ }
+ }
binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
bt_reset_linkage_2, NULL);
}
@@ -2712,7 +2751,7 @@ tentative_decl_linkage (tree decl)
DECL_INTERFACE_KNOWN (decl) = 1;
}
}
- else if (TREE_CODE (decl) == VAR_DECL)
+ else if (VAR_P (decl))
maybe_commonize_var (decl);
}
}
@@ -3017,6 +3056,7 @@ get_guard (tree decl)
TREE_STATIC (guard) = TREE_STATIC (decl);
DECL_COMMON (guard) = DECL_COMMON (decl);
DECL_COMDAT (guard) = DECL_COMDAT (decl);
+ CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl);
set_decl_tls_model (guard, DECL_TLS_MODEL (decl));
if (DECL_ONE_ONLY (decl))
make_decl_one_only (guard, cxx_comdat_group (guard));
@@ -3033,6 +3073,27 @@ get_guard (tree decl)
return guard;
}
+/* Return an atomic load of src with the appropriate memory model. */
+
+static tree
+build_atomic_load_byte (tree src, HOST_WIDE_INT model)
+{
+ tree ptr_type = build_pointer_type (char_type_node);
+ tree mem_model = build_int_cst (integer_type_node, model);
+ tree t, addr, val;
+ unsigned int size;
+ int fncode;
+
+ size = tree_to_uhwi (TYPE_SIZE_UNIT (char_type_node));
+
+ fncode = BUILT_IN_ATOMIC_LOAD_N + exact_log2 (size) + 1;
+ t = builtin_decl_implicit ((enum built_in_function) fncode);
+
+ addr = build1 (ADDR_EXPR, ptr_type, src);
+ val = build_call_expr (t, 2, addr, mem_model);
+ return val;
+}
+
/* Return those bits of the GUARD variable that should be set when the
guarded entity is actually initialized. */
@@ -3059,19 +3120,21 @@ get_guard_bits (tree guard)
variable has already been initialized. */
tree
-get_guard_cond (tree guard)
+get_guard_cond (tree guard, bool thread_safe)
{
tree guard_value;
- /* Check to see if the GUARD is zero. */
- guard = get_guard_bits (guard);
+ if (!thread_safe)
+ guard = get_guard_bits (guard);
+ else
+ guard = build_atomic_load_byte (guard, MEMMODEL_ACQUIRE);
/* Mask off all but the low bit. */
if (targetm.cxx.guard_mask_bit ())
{
guard_value = integer_one_node;
if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
- guard_value = convert (TREE_TYPE (guard), guard_value);
+ guard_value = fold_convert (TREE_TYPE (guard), guard_value);
guard = cp_build_binary_op (input_location,
BIT_AND_EXPR, guard, guard_value,
tf_warning_or_error);
@@ -3079,7 +3142,7 @@ get_guard_cond (tree guard)
guard_value = integer_zero_node;
if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
- guard_value = convert (TREE_TYPE (guard), guard_value);
+ guard_value = fold_convert (TREE_TYPE (guard), guard_value);
return cp_build_binary_op (input_location,
EQ_EXPR, guard, guard_value,
tf_warning_or_error);
@@ -3097,7 +3160,7 @@ set_guard (tree guard)
guard = get_guard_bits (guard);
guard_init = integer_one_node;
if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
- guard_init = convert (TREE_TYPE (guard), guard_init);
+ guard_init = fold_convert (TREE_TYPE (guard), guard_init);
return cp_build_modify_expr (guard, NOP_EXPR, guard_init,
tf_warning_or_error);
}
@@ -3132,7 +3195,7 @@ static bool
var_needs_tls_wrapper (tree var)
{
return (!error_operand_p (var)
- && DECL_THREAD_LOCAL_P (var)
+ && CP_DECL_THREAD_LOCAL_P (var)
&& !DECL_GNU_TLS_P (var)
&& !DECL_FUNCTION_SCOPE_P (var)
&& !var_defined_without_dynamic_init (var));
@@ -3680,7 +3743,7 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp)
/* When using __cxa_atexit, we never try to destroy
anything from a static destructor. */
gcc_assert (initp);
- guard_cond = get_guard_cond (guard);
+ guard_cond = get_guard_cond (guard, false);
}
/* If we don't have __cxa_atexit, then we will be running
destructors from .fini sections, or their equivalents. So,
@@ -4001,20 +4064,17 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
}
/* Java requires that we be able to reference a local address for a
- method, and not be confused by PLT entries. If hidden aliases are
- supported, collect and return all the functions for which we should
- emit a hidden alias. */
+ method, and not be confused by PLT entries. If supported, create a
+ hidden alias for all such methods. */
-static hash_set<tree> *
-collect_candidates_for_java_method_aliases (void)
+static void
+build_java_method_aliases (void)
{
- struct cgraph_node *node;
- hash_set<tree> *candidates = NULL;
-
#ifndef HAVE_GAS_HIDDEN
- return candidates;
+ return;
#endif
+ struct cgraph_node *node;
FOR_EACH_FUNCTION (node)
{
tree fndecl = node->decl;
@@ -4023,55 +4083,18 @@ collect_candidates_for_java_method_aliases (void)
&& TYPE_FOR_JAVA (DECL_CONTEXT (fndecl))
&& TARGET_USE_LOCAL_THUNK_ALIAS_P (fndecl))
{
- if (candidates == NULL)
- candidates = new hash_set<tree>;
- candidates->add (fndecl);
- }
- }
-
- return candidates;
-}
-
-
-/* Java requires that we be able to reference a local address for a
- method, and not be confused by PLT entries. If hidden aliases are
- supported, emit one for each java function that we've emitted.
- CANDIDATES is the set of FUNCTION_DECLs that were gathered
- by collect_candidates_for_java_method_aliases. */
-
-static void
-build_java_method_aliases (hash_set<tree> *candidates)
-{
- struct cgraph_node *node;
-
-#ifndef HAVE_GAS_HIDDEN
- return;
-#endif
-
- FOR_EACH_FUNCTION (node)
- {
- tree fndecl = node->decl;
-
- if (TREE_ASM_WRITTEN (fndecl)
- && candidates->contains (fndecl))
- {
/* Mangle the name in a predictable way; we need to reference
this from a java compiled object file. */
- tree oid, nid, alias;
- const char *oname;
- char *nname;
-
- oid = DECL_ASSEMBLER_NAME (fndecl);
- oname = IDENTIFIER_POINTER (oid);
+ tree oid = DECL_ASSEMBLER_NAME (fndecl);
+ const char *oname = IDENTIFIER_POINTER (oid);
gcc_assert (oname[0] == '_' && oname[1] == 'Z');
- nname = ACONCAT (("_ZGA", oname+2, NULL));
- nid = get_identifier (nname);
+ char *nname = ACONCAT (("_ZGA", oname + 2, NULL));
- alias = make_alias_for (fndecl, nid);
+ tree alias = make_alias_for (fndecl, get_identifier (nname));
TREE_PUBLIC (alias) = 1;
DECL_VISIBILITY (alias) = VISIBILITY_HIDDEN;
- assemble_alias (alias, oid);
+ cgraph_node::create_same_body_alias (alias, fndecl);
}
}
}
@@ -4083,6 +4106,16 @@ cpp_check (tree t, cpp_operation op)
{
switch (op)
{
+ case HAS_DEPENDENT_TEMPLATE_ARGS:
+ {
+ tree ti = CLASSTYPE_TEMPLATE_INFO (t);
+ if (!ti)
+ return 0;
+ ++processing_template_decl;
+ const bool dep = any_dependent_template_arguments_p (TI_ARGS (ti));
+ --processing_template_decl;
+ return dep;
+ }
case IS_ABSTRACT:
return DECL_PURE_VIRTUAL_P (t);
case IS_CONSTRUCTOR:
@@ -4091,6 +4124,8 @@ cpp_check (tree t, cpp_operation op)
return DECL_DESTRUCTOR_P (t);
case IS_COPY_CONSTRUCTOR:
return DECL_COPY_CONSTRUCTOR_P (t);
+ case IS_MOVE_CONSTRUCTOR:
+ return DECL_MOVE_CONSTRUCTOR_P (t);
case IS_TEMPLATE:
return TREE_CODE (t) == TEMPLATE_DECL;
case IS_TRIVIAL:
@@ -4197,6 +4232,9 @@ decl_maybe_constant_var_p (tree decl)
return false;
if (DECL_DECLARED_CONSTEXPR_P (decl))
return true;
+ if (DECL_HAS_VALUE_EXPR_P (decl))
+ /* A proxy isn't constant. */
+ return false;
return (CP_TYPE_CONST_NON_VOLATILE_P (type)
&& INTEGRAL_OR_ENUMERATION_TYPE_P (type));
}
@@ -4226,7 +4264,7 @@ no_linkage_error (tree decl)
"anonymous type, is used but never defined", decl);
else if (DECL_EXTERN_C_P (decl))
/* Allow this; it's pretty common in C. */;
- else if (TREE_CODE (decl) == VAR_DECL)
+ else if (VAR_P (decl))
/* DRs 132, 319 and 389 seem to indicate types with
no linkage can only be used to declare extern "C"
entities. Since it's not always an error in the
@@ -4245,12 +4283,12 @@ no_linkage_error (tree decl)
}
else if (cxx_dialect >= cxx11)
{
- if (TREE_CODE (decl) == VAR_DECL || !DECL_PURE_VIRTUAL_P (decl))
+ if (VAR_P (decl) || !DECL_PURE_VIRTUAL_P (decl))
permerror (DECL_SOURCE_LOCATION (decl),
"%q#D, declared using local type "
"%qT, is used but never defined", decl, t);
}
- else if (TREE_CODE (decl) == VAR_DECL)
+ else if (VAR_P (decl))
warning_at (DECL_SOURCE_LOCATION (decl), 0, "type %qT with no linkage "
"used to declare variable %q#D with linkage", t, decl);
else
@@ -4297,6 +4335,7 @@ handle_tls_init (void)
DECL_ARTIFICIAL (guard) = true;
DECL_IGNORED_P (guard) = true;
TREE_USED (guard) = true;
+ CP_DECL_THREAD_LOCAL_P (guard) = true;
set_decl_tls_model (guard, decl_default_tls_model (guard));
pushdecl_top_level_and_finish (guard, NULL_TREE);
@@ -4415,6 +4454,8 @@ dump_tu (void)
}
}
+static location_t locus_at_end_of_parsing;
+
/* Check the deallocation functions for CODE to see if we want to warn that
only one was defined. */
@@ -4456,24 +4497,38 @@ maybe_warn_sized_delete ()
maybe_warn_sized_delete (VEC_DELETE_EXPR);
}
+/* Earlier we left PTRMEM_CST in variable initializers alone so that we could
+ look them up when evaluating non-type template parameters. Now we need to
+ lower them to something the back end can understand. */
+
+static void
+lower_var_init ()
+{
+ varpool_node *node;
+ FOR_EACH_VARIABLE (node)
+ {
+ tree d = node->decl;
+ if (tree init = DECL_INITIAL (d))
+ DECL_INITIAL (d) = cplus_expand_constant (init);
+ }
+}
+
/* 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)
+c_parse_final_cleanups (void)
{
tree vars;
bool reconsider;
size_t i;
- location_t locus;
unsigned ssdf_count = 0;
int retries = 0;
tree decl;
- hash_set<tree> *candidates;
- locus = input_location;
+ locus_at_end_of_parsing = input_location;
at_eof = 1;
/* Bad parse errors. Just forget about it. */
@@ -4485,11 +4540,20 @@ cp_write_global_declarations (void)
In that case we do not want to do anything else. */
if (pch_file)
{
+ /* Mangle all symbols at PCH creation time. */
+ symtab_node *node;
+ FOR_EACH_SYMBOL (node)
+ if (! is_a <varpool_node *> (node)
+ || ! DECL_HARD_REGISTER (node->decl))
+ DECL_ASSEMBLER_NAME (node->decl);
c_common_write_pch ();
dump_tu ();
return;
}
+ timevar_stop (TV_PHASE_PARSING);
+ timevar_start (TV_PHASE_DEFERRED);
+
symtab->process_same_body_aliases ();
/* Handle -fdump-ada-spec[-slim] */
@@ -4505,8 +4569,6 @@ cp_write_global_declarations (void)
/* 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:
@@ -4602,7 +4664,7 @@ cp_write_global_declarations (void)
/* Set the line and file, so that it is obviously not from
the source file. */
- input_location = locus;
+ input_location = locus_at_end_of_parsing;
ssdf_body = start_static_storage_duration_function (ssdf_count);
/* Make sure the back end knows about all the variables. */
@@ -4628,7 +4690,7 @@ cp_write_global_declarations (void)
/* Finish up the static storage duration function for this
round. */
- input_location = locus;
+ input_location = locus_at_end_of_parsing;
finish_static_storage_duration_function (ssdf_body);
/* All those initializations and finalizations might cause
@@ -4636,7 +4698,7 @@ cp_write_global_declarations (void)
instantiations, etc. */
reconsider = true;
ssdf_count++;
- /* ??? was: locus.line++; */
+ /* ??? was: locus_at_end_of_parsing.line++; */
}
/* Now do the same for thread_local variables. */
@@ -4760,6 +4822,8 @@ cp_write_global_declarations (void)
}
while (reconsider);
+ lower_var_init ();
+
generate_mangling_aliases ();
/* All used inline functions must have a definition at this point. */
@@ -4778,8 +4842,9 @@ cp_write_global_declarations (void)
&& DECL_INITIAL (DECL_TEMPLATE_RESULT
(template_for_substitution (decl)))))
{
- warning (0, "inline function %q+D used but never defined", decl);
- /* Avoid a duplicate warning from check_global_declaration_1. */
+ warning_at (DECL_SOURCE_LOCATION (decl), 0,
+ "inline function %qD used but never defined", decl);
+ /* Avoid a duplicate warning from check_global_declaration. */
TREE_NO_WARNING (decl) = 1;
}
}
@@ -4806,12 +4871,13 @@ cp_write_global_declarations (void)
if (priority_info_map)
splay_tree_foreach (priority_info_map,
generate_ctor_and_dtor_functions_for_priority,
- /*data=*/&locus);
+ /*data=*/&locus_at_end_of_parsing);
else if (c_dialect_objc () && objc_static_init_needed_p ())
/* If this is obj-c++ and we need a static init, call
generate_ctor_or_dtor_function. */
generate_ctor_or_dtor_function (/*constructor_p=*/true,
- DEFAULT_INIT_PRIORITY, &locus);
+ DEFAULT_INIT_PRIORITY,
+ &locus_at_end_of_parsing);
/* We're done with the splay-tree now. */
if (priority_info_map)
@@ -4824,11 +4890,8 @@ cp_write_global_declarations (void)
linkage now. */
pop_lang_context ();
- /* Collect candidates for Java hidden aliases. */
- candidates = collect_candidates_for_java_method_aliases ();
-
- timevar_stop (TV_PHASE_DEFERRED);
- timevar_start (TV_PHASE_OPT_GEN);
+ /* Generate Java hidden aliases. */
+ build_java_method_aliases ();
if (flag_vtable_verify)
{
@@ -4837,43 +4900,12 @@ cp_write_global_declarations (void)
vtv_build_vtable_verify_fndecl ();
}
- symtab->finalize_compilation_unit ();
-
- if (flag_vtable_verify)
- {
- /* Generate the special constructor initialization function that
- calls __VLTRegisterPairs, and give it a very high
- initialization priority. This must be done after
- finalize_compilation_unit so that we have accurate
- information about which vtable will actually be emitted. */
- vtv_generate_init_routine ();
- }
-
- timevar_stop (TV_PHASE_OPT_GEN);
- timevar_start (TV_PHASE_CHECK_DBGINFO);
-
- /* Now, issue warnings about static, but not defined, functions,
- etc., and emit debugging information. */
- walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
- if (vec_safe_length (pending_statics) != 0)
- {
- check_global_declarations (pending_statics->address (),
- pending_statics->length ());
- emit_debug_global_declarations (pending_statics->address (),
- pending_statics->length ());
- }
-
perform_deferred_noexcept_checks ();
- /* Generate hidden aliases for Java. */
- if (candidates)
- {
- build_java_method_aliases (candidates);
- delete candidates;
- }
-
finish_repo ();
+ fini_constexpr ();
+
/* The entire file is now complete. If requested, dump everything
to a file. */
dump_tu ();
@@ -4883,13 +4915,39 @@ cp_write_global_declarations (void)
dump_tree_statistics ();
dump_time_statistics ();
}
- input_location = locus;
-#ifdef ENABLE_CHECKING
- validate_conversion_obstack ();
-#endif /* ENABLE_CHECKING */
+ timevar_stop (TV_PHASE_DEFERRED);
+ timevar_start (TV_PHASE_PARSING);
- timevar_stop (TV_PHASE_CHECK_DBGINFO);
+ /* Indicate that we're done with front end processing. */
+ at_eof = 2;
+}
+
+/* Perform any post compilation-proper cleanups for the C++ front-end.
+ This should really go away. No front-end should need to do
+ anything past the compilation process. */
+
+void
+cxx_post_compilation_parsing_cleanups (void)
+{
+ timevar_start (TV_PHASE_LATE_PARSING_CLEANUPS);
+
+ if (flag_vtable_verify)
+ {
+ /* Generate the special constructor initialization function that
+ calls __VLTRegisterPairs, and give it a very high
+ initialization priority. This must be done after
+ finalize_compilation_unit so that we have accurate
+ information about which vtable will actually be emitted. */
+ vtv_generate_init_routine ();
+ }
+
+ input_location = locus_at_end_of_parsing;
+
+ if (flag_checking)
+ validate_conversion_obstack ();
+
+ timevar_stop (TV_PHASE_LATE_PARSING_CLEANUPS);
}
/* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
@@ -5020,6 +5078,10 @@ mark_used (tree decl, tsubst_flags_t complain)
/* Set TREE_USED for the benefit of -Wunused. */
TREE_USED (decl) = 1;
+
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ return true;
+
if (DECL_CLONED_FUNCTION_P (decl))
TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
@@ -5080,14 +5142,6 @@ mark_used (tree decl, tsubst_flags_t complain)
if (DECL_ODR_USED (decl))
return true;
- /* If within finish_function, defer the rest until that function
- finishes, otherwise it might recurse. */
- if (defer_mark_used_calls)
- {
- vec_safe_push (deferred_mark_used_calls, decl);
- return true;
- }
-
/* Normally, we can wait until instantiation-time to synthesize DECL.
However, if DECL is a static data member initialized with a constant
or a constexpr function, we need it right now because a reference to
@@ -5102,6 +5156,7 @@ mark_used (tree decl, tsubst_flags_t complain)
|| (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_OMP_DECLARE_REDUCTION_P (decl))
|| undeduced_auto_decl (decl))
+ && !DECL_DECLARED_CONCEPT_P (decl)
&& !uses_template_parms (DECL_TI_ARGS (decl)))
{
/* Instantiating a function will result in garbage collection. We
@@ -5200,6 +5255,7 @@ mark_used (tree decl, tsubst_flags_t complain)
}
else if (VAR_OR_FUNCTION_DECL_P (decl)
&& DECL_TEMPLATE_INFO (decl)
+ && !DECL_DECLARED_CONCEPT_P (decl)
&& (!DECL_EXPLICIT_INSTANTIATION (decl)
|| always_instantiate_p (decl)))
/* If this is a function or variable that is an instance of some