+static void check_deprecated(const source_position_t *source_position,
+ const entity_t *entity)
+{
+ if (!warning.deprecated_declarations)
+ return;
+ if (!is_declaration(entity))
+ return;
+ if ((entity->declaration.modifiers & DM_DEPRECATED) == 0)
+ return;
+
+ char const *const prefix = get_entity_kind_name(entity->kind);
+ const char *deprecated_string
+ = get_deprecated_string(entity->declaration.attributes);
+ if (deprecated_string != NULL) {
+ warningf(source_position, "%s '%Y' is deprecated (declared %P): \"%s\"",
+ prefix, entity->base.symbol, &entity->base.source_position,
+ deprecated_string);
+ } else {
+ warningf(source_position, "%s '%Y' is deprecated (declared %P)", prefix,
+ entity->base.symbol, &entity->base.source_position);
+ }
+}
+
+
+static expression_t *create_select(const source_position_t *pos,
+ expression_t *addr,
+ type_qualifiers_t qualifiers,
+ entity_t *entry)
+{
+ assert(entry->kind == ENTITY_COMPOUND_MEMBER);
+
+ check_deprecated(pos, entry);
+
+ expression_t *select = allocate_expression_zero(EXPR_SELECT);
+ select->select.compound = addr;
+ select->select.compound_entry = entry;
+
+ type_t *entry_type = entry->declaration.type;
+ type_t *res_type = get_qualified_type(entry_type, qualifiers);
+
+ /* we always do the auto-type conversions; the & and sizeof parser contains
+ * code to revert this! */
+ select->base.type = automatic_type_conversion(res_type);
+ if (res_type->kind == TYPE_BITFIELD) {
+ select->base.type = res_type->bitfield.base_type;
+ }
+
+ return select;
+}
+
+/**
+ * Find entry with symbol in compound. Search anonymous structs and unions and
+ * creates implicit select expressions for them.
+ * Returns the adress for the innermost compound.
+ */
+static expression_t *find_create_select(const source_position_t *pos,
+ expression_t *addr,
+ type_qualifiers_t qualifiers,
+ compound_t *compound, symbol_t *symbol)
+{
+ entity_t *iter = compound->members.entities;
+ for (; iter != NULL; iter = iter->base.next) {
+ if (iter->kind != ENTITY_COMPOUND_MEMBER)
+ continue;
+
+ symbol_t *iter_symbol = iter->base.symbol;
+ if (iter_symbol == NULL) {
+ type_t *type = iter->declaration.type;
+ if (type->kind != TYPE_COMPOUND_STRUCT
+ && type->kind != TYPE_COMPOUND_UNION)
+ continue;
+
+ compound_t *sub_compound = type->compound.compound;
+
+ if (find_compound_entry(sub_compound, symbol) == NULL)
+ continue;
+
+ expression_t *sub_addr = create_select(pos, addr, qualifiers, iter);
+ sub_addr->base.source_position = *pos;
+ sub_addr->select.implicit = true;
+ return find_create_select(pos, sub_addr, qualifiers, sub_compound,
+ symbol);
+ }
+
+ if (iter_symbol == symbol) {
+ return create_select(pos, addr, qualifiers, iter);
+ }
+ }
+
+ return NULL;
+}
+