+static void semantic_complex_extract(unary_expression_t *extract)
+{
+ type_t *orig_value_type = extract->value->base.type;
+ type_t *value_type = skip_typeref(orig_value_type);
+ if (!is_type_valid(value_type)) {
+ extract->base.type = type_error_type;
+ return;
+ }
+
+ type_t *type = value_type;
+ if (!is_type_complex(type)) {
+ if (!is_type_arithmetic(type)) {
+ errorf(&extract->base.pos,
+ "%s requires an argument with complex or arithmetic type, got '%T'",
+ extract->base.kind == EXPR_UNARY_IMAG ? "__imag__" : "__real__",
+ orig_value_type);
+ extract->base.type = type_error_type;
+ return;
+ }
+ atomic_type_kind_t const akind = get_arithmetic_akind(type);
+ type = make_complex_type(akind, TYPE_QUALIFIER_NONE);
+ extract->value = create_implicit_cast(extract->value, type);
+ }
+ assert(type->kind == TYPE_COMPLEX);
+ type = make_atomic_type(type->atomic.akind, TYPE_QUALIFIER_NONE);
+ extract->base.type = type;
+}
+
+static expression_t *parse_compound_literal(position_t const *const pos,
+ type_t *type)