#include "target.h"
#include "function.h"
#include "bitmap.h"
-#include "tree.h"
-#include "c-family/c-common.h"
#include "c-tree.h"
#include "gimple-expr.h"
#include "predict.h"
#include "stmt.h"
#include "langhooks.h"
#include "c-lang.h"
-#include "flags.h"
#include "intl.h"
#include "tree-iterator.h"
#include "gimplify.h"
#include "c-family/c-ubsan.h"
#include "cilk.h"
#include "gomp-constants.h"
+#include "spellcheck.h"
/* Possible cases of implicit bad conversions. Used to select
diagnostic messages in convert_for_assignment. */
while (DECL_NAME (field_array[bot]) == NULL_TREE)
{
field = field_array[bot++];
- if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
- || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)))
{
tree anon = lookup_field (TREE_TYPE (field), component);
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
{
if (DECL_NAME (field) == NULL_TREE
- && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
- || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)))
{
tree anon = lookup_field (TREE_TYPE (field), component);
return tree_cons (NULL_TREE, field, NULL_TREE);
}
+/* Recursively append candidate IDENTIFIER_NODEs to CANDIDATES. */
+
+static void
+lookup_field_fuzzy_find_candidates (tree type, tree component,
+ vec<tree> *candidates)
+{
+ tree field;
+ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ if (DECL_NAME (field) == NULL_TREE
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)))
+ lookup_field_fuzzy_find_candidates (TREE_TYPE (field), component,
+ candidates);
+
+ if (DECL_NAME (field))
+ candidates->safe_push (DECL_NAME (field));
+ }
+}
+
+/* Like "lookup_field", but find the closest matching IDENTIFIER_NODE,
+ rather than returning a TREE_LIST for an exact match. */
+
+static tree
+lookup_field_fuzzy (tree type, tree component)
+{
+ gcc_assert (TREE_CODE (component) == IDENTIFIER_NODE);
+
+ /* First, gather a list of candidates. */
+ auto_vec <tree> candidates;
+
+ lookup_field_fuzzy_find_candidates (type, component,
+ &candidates);
+
+ /* Now determine which is closest. */
+ int i;
+ tree identifier;
+ tree best_identifier = NULL;
+ edit_distance_t best_distance = MAX_EDIT_DISTANCE;
+ FOR_EACH_VEC_ELT (candidates, i, identifier)
+ {
+ gcc_assert (TREE_CODE (identifier) == IDENTIFIER_NODE);
+ edit_distance_t dist = levenshtein_distance (component, identifier);
+ if (dist < best_distance)
+ {
+ best_distance = dist;
+ best_identifier = identifier;
+ }
+ }
+
+ /* If more than half of the letters were misspelled, the suggestion is
+ likely to be meaningless. */
+ if (best_identifier)
+ {
+ unsigned int cutoff = MAX (IDENTIFIER_LENGTH (component),
+ IDENTIFIER_LENGTH (best_identifier)) / 2;
+ if (best_distance > cutoff)
+ return NULL;
+ }
+
+ return best_identifier;
+}
+
/* Make an expression to refer to the COMPONENT field of structure or
union value DATUM. COMPONENT is an IDENTIFIER_NODE. LOC is the
location of the COMPONENT_REF. */
if (!field)
{
- error_at (loc, "%qT has no member named %qE", type, component);
+ tree guessed_id = lookup_field_fuzzy (type, component);
+ if (guessed_id)
+ error_at (loc, "%qT has no member named %qE; did you mean %qE?",
+ type, component, guessed_id);
+ else
+ error_at (loc, "%qT has no member named %qE", type, component);
return error_mark_node;
}
overflow_warning (loc, result.value);
}
+ /* We are typically called when parsing a prefix token at LOC acting on
+ ARG. Reflect this by updating the source range of the result to
+ start at LOC and end at the end of ARG. */
+ set_c_expr_source_range (&result,
+ loc, arg.get_finish ());
+
return result;
}
if (location != UNKNOWN_LOCATION)
protected_set_expr_location (result.value, location);
+ set_c_expr_source_range (&result,
+ arg1.get_start (),
+ arg2.get_finish ());
+
/* Check for cases such as x+y<<z which users are likely
to misinterpret. */
if (warn_parentheses)
if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
{
- if (TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (type))
pedwarn (loc, OPT_Wpedantic,
"ISO C forbids casting nonscalar to the same type");
&& TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
/* Don't warn about opaque types, where the actual alignment
restriction is unknown. */
- && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE
- || TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
+ && !(RECORD_OR_UNION_TYPE_P (TREE_TYPE (otype))
&& TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
&& TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
warning_at (loc, OPT_Wcast_align,
/* Give an error for storing in something that is 'const'. */
if (TYPE_READONLY (lhstype)
- || ((TREE_CODE (lhstype) == RECORD_TYPE
- || TREE_CODE (lhstype) == UNION_TYPE)
+ || (RECORD_OR_UNION_TYPE_P (lhstype)
&& C_TYPE_FIELDS_READONLY (lhstype)))
{
readonly_error (location, lhs, lv_assign);
tree field;
bool found;
- gcc_assert (TREE_CODE (struct_type) == RECORD_TYPE
- || TREE_CODE (struct_type) == UNION_TYPE);
+ gcc_assert (RECORD_OR_UNION_TYPE_P (struct_type));
found = false;
for (field = TYPE_FIELDS (struct_type);
field != NULL_TREE;
found = true;
}
else if (DECL_NAME (field) == NULL
- && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
- || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
&& find_anonymous_field_with_type (TREE_TYPE (field), type))
{
if (found)
gcc_assert (POINTER_TYPE_P (TREE_TYPE (rhs)));
rhs_struct_type = TREE_TYPE (TREE_TYPE (rhs));
- gcc_assert (TREE_CODE (rhs_struct_type) == RECORD_TYPE
- || TREE_CODE (rhs_struct_type) == UNION_TYPE);
+ gcc_assert (RECORD_OR_UNION_TYPE_P (rhs_struct_type));
gcc_assert (POINTER_TYPE_P (type));
lhs_main_type = (TYPE_ATOMIC (TREE_TYPE (type))
field = TREE_CHAIN (field))
{
if (DECL_NAME (field) != NULL_TREE
- || (TREE_CODE (TREE_TYPE (field)) != RECORD_TYPE
- && TREE_CODE (TREE_TYPE (field)) != UNION_TYPE))
+ || !RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)))
continue;
tree fieldtype = (TYPE_ATOMIC (TREE_TYPE (field))
? c_build_qualified_type (TREE_TYPE (field),
automatically converted into a pointer to an anonymous field
within the struct. */
if (flag_plan9_extensions
- && (TREE_CODE (mvl) == RECORD_TYPE || TREE_CODE(mvl) == UNION_TYPE)
- && (TREE_CODE (mvr) == RECORD_TYPE || TREE_CODE(mvr) == UNION_TYPE)
+ && RECORD_OR_UNION_TYPE_P (mvl)
+ && RECORD_OR_UNION_TYPE_P (mvr)
&& mvl != mvr)
{
tree new_rhs = convert_to_anonymous_field (location, type, rhs);
designator_depth = 0;
designator_erroneous = 0;
- if (TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (constructor_type))
{
constructor_fields = TYPE_FIELDS (constructor_type);
/* Skip any nameless bit fields at the beginning. */
{
while (constructor_stack->implicit)
{
- if ((TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (constructor_type)
&& constructor_fields == 0)
process_init_element (input_location,
pop_init_level (loc, 1, braced_init_obstack),
content if any. */
if (implicit)
{
- if ((TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
- && constructor_fields)
+ if (RECORD_OR_UNION_TYPE_P (constructor_type) && constructor_fields)
value = find_init_member (constructor_fields, braced_init_obstack);
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
value = find_init_member (constructor_index, braced_init_obstack);
in the containing level. */
if (constructor_type == 0)
;
- else if (TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ else if (RECORD_OR_UNION_TYPE_P (constructor_type))
{
/* Don't die if there are extra init elts at the end. */
if (constructor_fields == 0)
if (implicit == 1)
found_missing_braces = 1;
- if (TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (constructor_type))
{
constructor_fields = TYPE_FIELDS (constructor_type);
/* Skip any nameless bit fields at the beginning. */
ret = p->replacement_value;
else if (constructor_type == 0)
;
- else if (TREE_CODE (constructor_type) != RECORD_TYPE
- && TREE_CODE (constructor_type) != UNION_TYPE
+ else if (!RECORD_OR_UNION_TYPE_P (constructor_type)
&& TREE_CODE (constructor_type) != ARRAY_TYPE
&& !VECTOR_TYPE_P (constructor_type))
{
designator_erroneous = 1;
- if (TREE_CODE (constructor_type) != RECORD_TYPE
- && TREE_CODE (constructor_type) != UNION_TYPE)
+ if (!RECORD_OR_UNION_TYPE_P (constructor_type))
{
error_init (loc, "field name not in record or union initializer");
return;
AGGREGATE_TYPE_P (constructor_type)
&& TYPE_REVERSE_STORAGE_ORDER
(constructor_type))
- || ((TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ || (RECORD_OR_UNION_TYPE_P (constructor_type)
&& DECL_C_BIT_FIELD (field)
&& TREE_CODE (value) != INTEGER_CST))
constructor_simple = 0;
}
}
}
- else if (TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ else if (RECORD_OR_UNION_TYPE_P (constructor_type))
{
tree ctor_unfilled_bitpos, elt_bitpos;
/* If it's not incremental, just skip over the gap, so that after
jumping to retry we will output the next successive element. */
- if (TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (constructor_type))
constructor_unfilled_fields = next;
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
constructor_unfilled_index = next;
pop them now. */
while (constructor_stack->implicit)
{
- if ((TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (constructor_type)
&& constructor_fields == 0)
process_init_element (loc,
pop_init_level (loc, 1, braced_init_obstack),
if (output != error_mark_node
&& (TREE_READONLY (output)
|| TYPE_READONLY (TREE_TYPE (output))
- || ((TREE_CODE (TREE_TYPE (output)) == RECORD_TYPE
- || TREE_CODE (TREE_TYPE (output)) == UNION_TYPE)
+ || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (output))
&& C_TYPE_FIELDS_READONLY (TREE_TYPE (output)))))
readonly_error (loc, output, lv_asm);
exit = fold_build3_loc (input_location,
COND_EXPR, void_type_node, cond, exit, t);
}
+ else
+ {
+ /* For the backward-goto's location of an unconditional loop
+ use the beginning of the body, or, if there is none, the
+ top of the loop. */
+ location_t loc = EXPR_LOCATION (expr_first (body));
+ if (loc == UNKNOWN_LOCATION)
+ loc = start_locus;
+ SET_EXPR_LOCATION (exit, loc);
+ }
add_stmt (top);
}
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
- else if (!c_mark_addressable (t))
+ else if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
+ || (OMP_CLAUSE_MAP_KIND (c)
+ != GOMP_MAP_FIRSTPRIVATE_POINTER))
+ && !c_mark_addressable (t))
remove = true;
else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
tree var_type = build_qualified_type (type, type_quals);
/* A variant type does not inherit the list of incomplete vars from the
type main variant. */
- if (TREE_CODE (var_type) == RECORD_TYPE
- || TREE_CODE (var_type) == UNION_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (var_type))
C_TYPE_INCOMPLETE_VARS (var_type) = 0;
return var_type;
}