+ 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;
+ }
+
+ if (specifiers->is_inline && is_type_valid(type)) {
+ errorf(&env.source_position,
+ "variable '%Y' declared 'inline'", env.symbol);
+ }
+
+ entity->variable.thread_local = specifiers->thread_local;
+
+ bool invalid_storage_class = false;
+ if (current_scope == file_scope) {
+ if (specifiers->storage_class != STORAGE_CLASS_EXTERN &&
+ specifiers->storage_class != STORAGE_CLASS_NONE &&
+ specifiers->storage_class != STORAGE_CLASS_STATIC) {
+ invalid_storage_class = true;
+ }
+ } else {
+ if (specifiers->thread_local &&
+ specifiers->storage_class == STORAGE_CLASS_NONE) {
+ invalid_storage_class = true;
+ }
+ }
+ if (invalid_storage_class) {
+ errorf(&env.source_position,
+ "invalid storage class for variable '%Y'", env.symbol);
+ }
+ }
+
+ entity->base.source_position = env.source_position;
+ entity->base.symbol = env.symbol;
+ entity->base.namespc = NAMESPACE_NORMAL;
+ entity->declaration.type = orig_type;
+ entity->declaration.modifiers = env.modifiers;
+ entity->declaration.deprecated_string = specifiers->deprecated_string;
+
+ storage_class_t storage_class = specifiers->storage_class;
+ entity->declaration.declared_storage_class = storage_class;
+
+ if (storage_class == STORAGE_CLASS_NONE
+ && current_scope != file_scope) {
+ storage_class = STORAGE_CLASS_AUTO;
+ }
+ entity->declaration.storage_class = storage_class;