#include "target.h"
#include "convert.h"
#include "tree-flow.h"
+#include "cgraph.h"
static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *);
return rval;
}
+/* Return a TARGET_EXPR which expresses the direct-initialization of one
+ array from another. */
+
+tree
+build_array_copy (tree init)
+{
+ tree type = TREE_TYPE (init);
+ tree slot = build_local_temp (type);
+ init = build2 (VEC_INIT_EXPR, type, slot, init);
+ SET_EXPR_LOCATION (init, input_location);
+ init = build_target_expr (slot, init);
+ TARGET_EXPR_IMPLICIT_P (init) = 1;
+
+ return init;
+}
+
/* Build a TARGET_EXPR using INIT to initialize a new temporary of the
indicated TYPE. */
Non-class rvalues always have cv-unqualified types. */
type = TREE_TYPE (expr);
- if (!CLASS_TYPE_P (type) && cp_type_quals (type))
- type = cp_build_qualified_type (type, TYPE_UNQUALIFIED);
+ if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
+ type = cv_unqualified (type);
/* We need to do this for rvalue refs as well to get the right answer
from decltype; see c++/36628. */
else
{
/* Build a new array type. */
- t = make_node (ARRAY_TYPE);
+ t = cxx_make_type (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
TYPE_DOMAIN (t) = index_type;
}
+/* Returns EXPR cast to rvalue reference type, like std::move. */
+
+tree
+move (tree expr)
+{
+ tree type = TREE_TYPE (expr);
+ gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
+ type = cp_build_reference_type (type, /*rval*/true);
+ return build_static_cast (type, expr, tf_warning_or_error);
+}
+
/* Used by the C++ front end to build qualified array types. However,
the C version of this function does not properly maintain canonical
types (which are not used in C). */
&& (TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result))
== TYPE_LANG_SPECIFIC (TYPE_CANONICAL (type))))
TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result)) = NULL;
-
return result;
}
+/* Return TYPE with const and volatile removed. */
+
+tree
+cv_unqualified (tree type)
+{
+ int quals = TYPE_QUALS (type);
+ quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
+ return cp_build_qualified_type (type, quals);
+}
+
/* Builds a qualified variant of T that is not a typedef variant.
E.g. consider the following declarations:
typedef const int ConstInt;
else
result = build_function_type (type,
arg_types);
+
+ if (TYPE_RAISES_EXCEPTIONS (t))
+ result = build_exception_variant (result,
+ TYPE_RAISES_EXCEPTIONS (t));
}
break;
default:
if (!result)
result = TYPE_MAIN_VARIANT (t);
+ if (TYPE_ATTRIBUTES (t))
+ result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
return cp_build_qualified_type (result, cp_type_quals (t));
}
+/* Returns true iff TYPE is a type variant created for a typedef. */
+
+bool
+typedef_variant_p (tree type)
+{
+ return is_typedef_decl (TYPE_NAME (type));
+}
+
\f
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
graph dominated by T. If BINFO is NULL, TYPE is a dependent base,
return error_mark_node;
t = build2 (SCOPE_REF, type, scope, name);
QUALIFIED_NAME_IS_TEMPLATE (t) = template_p;
+ if (type)
+ t = convert_from_reference (t);
return t;
}
TEMPLATE_TYPE_PARM_INDEX (t2) = copy_node (TEMPLATE_TYPE_PARM_INDEX (t));
TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (t2)) = decl;
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)
- = tree_cons (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t),
- newargs, NULL_TREE);
+ = build_template_info (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t), newargs);
TREE_TYPE (decl) = t2;
TYPE_NAME (t2) = decl;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
goto ptrmem;
+ /* Lambda types that don't have mangling scope have no linkage. We
+ check CLASSTYPE_LAMBDA_EXPR here rather than LAMBDA_TYPE_P because
+ when we get here from pushtag none of the lambda information is
+ set up yet, so we want to assume that the lambda has linkage and
+ fix it up later if not. */
+ if (CLASSTYPE_LAMBDA_EXPR (t)
+ && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
+ return t;
/* Fall through. */
case UNION_TYPE:
if (!CLASS_TYPE_P (t))
return NULL_TREE;
-
- /* Check template type-arguments. I think that types with no linkage
- can't occur in non-type arguments, though that might change with
- constexpr. */
- r = CLASSTYPE_TEMPLATE_INFO (t);
- if (r)
- {
- tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (r));
- int i;
-
- for (i = TREE_VEC_LENGTH (args); i-- > 0; )
- {
- tree elt = TREE_VEC_ELT (args, i);
- if (TYPE_P (elt)
- && (r = no_linkage_check (elt, relaxed_p), r))
- return r;
- }
- }
/* Fall through. */
case ENUMERAL_TYPE:
/* Only treat anonymous types as having no linkage if they're at
if (TYPE_ANONYMOUS_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
return t;
- r = CP_TYPE_CONTEXT (t);
- if (TYPE_P (r))
- return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
- else if (TREE_CODE (r) == FUNCTION_DECL)
+ for (r = CP_TYPE_CONTEXT (t); ; )
{
- if (!relaxed_p || !TREE_PUBLIC (r) || !vague_linkage_fn_p (r))
- return t;
+ /* If we're a nested type of a !TREE_PUBLIC class, we might not
+ have linkage, or we might just be in an anonymous namespace.
+ If we're in a TREE_PUBLIC class, we have linkage. */
+ if (TYPE_P (r) && !TREE_PUBLIC (TYPE_NAME (r)))
+ return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
+ else if (TREE_CODE (r) == FUNCTION_DECL)
+ {
+ if (!relaxed_p || !vague_linkage_fn_p (r))
+ return t;
+ else
+ r = CP_DECL_CONTEXT (r);
+ }
else
- return no_linkage_check (CP_DECL_CONTEXT (r), relaxed_p);
+ break;
}
return NULL_TREE;
case TEMPLATE_PARM_INDEX:
return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
&& TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
+ && (TEMPLATE_PARM_PARAMETER_PACK (t1)
+ == TEMPLATE_PARM_PARAMETER_PACK (t2))
&& same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
tree new_type;
new_type = build_type_attribute_variant (type, attributes);
- if (TREE_CODE (new_type) == FUNCTION_TYPE
+ if ((TREE_CODE (new_type) == FUNCTION_TYPE
+ || TREE_CODE (new_type) == METHOD_TYPE)
&& (TYPE_RAISES_EXCEPTIONS (new_type)
!= TYPE_RAISES_EXCEPTIONS (type)))
new_type = build_exception_variant (new_type,
DECL_LANG_SPECIFIC. */
if (DECL_COPY_CONSTRUCTOR_P (decl))
return sfk_copy_constructor;
+ if (DECL_MOVE_CONSTRUCTOR_P (decl))
+ return sfk_move_constructor;
if (DECL_CONSTRUCTOR_P (decl))
return sfk_constructor;
if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
if (!gimple_has_body_p (decl)
&& !DECL_THUNK_P (decl)
&& !DECL_EXTERNAL (decl))
- return true;
+ {
+ struct cgraph_node *node = cgraph_get_node (decl);
+
+ /* Don't fix same_body aliases. Although they don't have their own
+ CFG, they share it with what they alias to. */
+ if (!node
+ || node->decl == decl
+ || !node->same_body)
+ return true;
+ }
return false;
}
DECL_EXTERNAL (t) = 1;
TREE_STATIC (t) = 0;
}
+ if (CP_AGGREGATE_TYPE_P (t)
+ && TYPE_NAME (t))
+ {
+ tree name = TYPE_NAME (t);
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = DECL_NAME (name);
+ /* Drop anonymous names. */
+ if (name != NULL_TREE
+ && ANON_AGGRNAME_P (name))
+ TYPE_NAME (t) = NULL_TREE;
+ }
}
\f