nullptr, expect_type);
}
+/* Helper for structop_base_operation::complete which recursively adds
+ field and method names from TYPE, a struct or union type, to the
+ OUTPUT list. PREFIX is prepended to each result. */
+
+static void
+add_struct_fields (struct type *type, completion_list &output,
+ const char *fieldname, int namelen, const char *prefix)
+{
+ int i;
+ int computed_type_name = 0;
+ const char *type_name = NULL;
+
+ type = check_typedef (type);
+ for (i = 0; i < type->num_fields (); ++i)
+ {
+ if (i < TYPE_N_BASECLASSES (type))
+ add_struct_fields (TYPE_BASECLASS (type, i),
+ output, fieldname, namelen, prefix);
+ else if (type->field (i).name ())
+ {
+ if (type->field (i).name ()[0] != '\0')
+ {
+ if (! strncmp (type->field (i).name (),
+ fieldname, namelen))
+ output.emplace_back (concat (prefix, type->field (i).name (),
+ nullptr));
+ }
+ else if (type->field (i).type ()->code () == TYPE_CODE_UNION)
+ {
+ /* Recurse into anonymous unions. */
+ add_struct_fields (type->field (i).type (),
+ output, fieldname, namelen, prefix);
+ }
+ }
+ }
+
+ for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
+ {
+ const char *name = TYPE_FN_FIELDLIST_NAME (type, i);
+
+ if (name && ! strncmp (name, fieldname, namelen))
+ {
+ if (!computed_type_name)
+ {
+ type_name = type->name ();
+ computed_type_name = 1;
+ }
+ /* Omit constructors from the completion list. */
+ if (!type_name || strcmp (type_name, name))
+ output.emplace_back (concat (prefix, name, nullptr));
+ }
+ }
+}
+
+/* See expop.h. */
+
+bool
+structop_base_operation::complete (struct expression *exp,
+ completion_tracker &tracker,
+ const char *prefix)
+{
+ const std::string &fieldname = std::get<1> (m_storage);
+
+ value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp,
+ EVAL_AVOID_SIDE_EFFECTS);
+ struct type *type = value_type (lhs);
+ for (;;)
+ {
+ type = check_typedef (type);
+ if (!type->is_pointer_or_reference ())
+ break;
+ type = TYPE_TARGET_TYPE (type);
+ }
+
+ if (type->code () == TYPE_CODE_UNION
+ || type->code () == TYPE_CODE_STRUCT)
+ {
+ completion_list result;
+
+ add_struct_fields (type, result, fieldname.c_str (),
+ fieldname.length (), prefix);
+ tracker.add_completions (std::move (result));
+ return true;
+ }
+
+ return false;
+}
} /* namespace expr */
lookup_child_selector (exp->gdbarch, sel));
}
-/* Helper function that implements the body of BINOP_CONCAT. */
-
-struct value *
-eval_op_concat (struct type *expect_type, struct expression *exp,
- enum noside noside, struct value *arg1, struct value *arg2)
-{
- if (binop_user_defined_p (BINOP_CONCAT, arg1, arg2))
- return value_x_binop (arg1, arg2, BINOP_CONCAT, OP_NULL, noside);
- else
- return value_concat (arg1, arg2);
-}
-
/* A helper function for TERNOP_SLICE. */
struct value *
return value_array (tem2, tem3, argvec);
}
+value *
+unop_extract_operation::evaluate (struct type *expect_type,
+ struct expression *exp,
+ enum noside noside)
+{
+ value *old_value = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
+ struct type *type = get_type ();
+
+ if (TYPE_LENGTH (type) > TYPE_LENGTH (value_type (old_value)))
+ error (_("length type is larger than the value type"));
+
+ struct value *result = allocate_value (type);
+ value_contents_copy (result, 0, old_value, 0, TYPE_LENGTH (type));
+ return result;
+}
+
}
\f