+ entity_t *entity;
+ if (specifiers->storage_class == STORAGE_CLASS_TYPEDEF) {
+ entity = allocate_entity_zero(ENTITY_TYPEDEF);
+ entity->base.symbol = env.symbol;
+ entity->base.source_position = env.source_position;
+ entity->typedefe.type = orig_type;
+
+ if (anonymous_entity != NULL) {
+ if (is_type_compound(type)) {
+ assert(anonymous_entity->compound.alias == NULL);
+ assert(anonymous_entity->kind == ENTITY_STRUCT ||
+ anonymous_entity->kind == ENTITY_UNION);
+ anonymous_entity->compound.alias = entity;
+ anonymous_entity = NULL;
+ } else if (is_type_enum(type)) {
+ assert(anonymous_entity->enume.alias == NULL);
+ assert(anonymous_entity->kind == ENTITY_ENUM);
+ anonymous_entity->enume.alias = entity;
+ anonymous_entity = NULL;
+ }
+ }
+ } else {
+ if (flags & DECL_CREATE_COMPOUND_MEMBER) {
+ entity = allocate_entity_zero(ENTITY_COMPOUND_MEMBER);
+
+ if (specifiers->is_inline && is_type_valid(type)) {
+ errorf(&env.source_position,
+ "compound member '%Y' declared 'inline'", env.symbol);
+ }
+
+ if (specifiers->thread_local ||
+ specifiers->storage_class != STORAGE_CLASS_NONE) {
+ errorf(&env.source_position,
+ "compound member '%Y' must have no storage class",
+ env.symbol);
+ }
+ } else if (flags & DECL_IS_PARAMETER) {
+ /* §6.7.5.3:7 A declaration of a parameter as ``array of type''
+ * shall be adjusted to ``qualified pointer to type'',
+ * [...]
+ * §6.7.5.3:8 A declaration of a parameter as ``function returning
+ * type'' shall be adjusted to ``pointer to function
+ * returning type'', as in 6.3.2.1. */
+ orig_type = automatic_type_conversion(type);
+ goto create_variable;
+ } else if (is_type_function(type)) {
+ entity = allocate_entity_zero(ENTITY_FUNCTION);
+
+ entity->function.is_inline = specifiers->is_inline;
+ entity->function.parameters = env.parameters;
+
+ if (specifiers->thread_local || (
+ specifiers->storage_class != STORAGE_CLASS_EXTERN &&
+ specifiers->storage_class != STORAGE_CLASS_NONE &&
+ specifiers->storage_class != STORAGE_CLASS_STATIC)
+ ) {
+ errorf(&env.source_position,
+ "invalid storage class for function '%Y'", env.symbol);
+ }
+ } else {
+create_variable:
+ entity = allocate_entity_zero(ENTITY_VARIABLE);
+
+ entity->variable.get_property_sym = specifiers->get_property_sym;
+ entity->variable.put_property_sym = specifiers->put_property_sym;
+ if (specifiers->alignment != 0) {
+ /* TODO: add checks here */
+ entity->variable.alignment = specifiers->alignment;
+ }