+static inline
+void *allocate_type_zero(size_t size)
+{
+ void *res = obstack_alloc(type_obst, size);
+ memset(res, 0, size);
+ return res;
+}
+
+/**
+ * pushs an environment_entry on the environment stack and links the
+ * corresponding symbol to the new entry
+ */
+static inline
+environment_entry_t *environment_push(symbol_t *symbol)
+{
+ environment_entry_t *entry
+ = obstack_alloc(&environment_obstack, sizeof(entry[0]));
+ memset(entry, 0, sizeof(entry[0]));
+
+ int top = ARR_LEN(environment_stack);
+ ARR_RESIZE(environment_stack, top + 1);
+ environment_stack[top] = entry;
+
+ entry->old_entry = symbol->thing;
+ entry->symbol = symbol;
+ symbol->thing = entry;
+
+ return entry;
+}
+
+/**
+ * pops symbols from the environment stack until @p new_top is the top element
+ */
+static inline
+void environment_pop_to(size_t new_top)
+{
+ environment_entry_t *entry = NULL;
+ size_t top = ARR_LEN(environment_stack);
+ size_t i;
+
+ if(new_top == top)
+ return;
+
+ assert(new_top < top);
+ i = top;
+ do {
+ entry = environment_stack[i - 1];
+
+ symbol_t *symbol = entry->symbol;
+
+#if 0
+ if(entry->type == ENTRY_LOCAL_VARIABLE
+ && entry->e.variable->refs == 0) {
+ variable_declaration_statement_t *variable = entry->e.variable;
+ print_warning_prefix(env, variable->statement.source_position);
+ fprintf(stderr, "variable '%s' was declared but never read\n",
+ symbol->string);
+ }
+#endif
+
+ if(entry->declaration->storage_class == STORAGE_CLASS_TYPEDEF) {
+ fprintf(stderr, "pop typename '%s'\n", entry->symbol->string);
+ symbol->ID = entry->old_symbol_ID;
+ }
+
+ assert(symbol->thing == entry);
+ symbol->thing = entry->old_entry;
+
+ --i;
+ } while(i != new_top);
+ obstack_free(&environment_obstack, entry);
+
+ ARR_SHRINKLEN(environment_stack, (int) new_top);
+}
+
+/**
+ * returns the top element of the environment stack
+ */
+static inline
+size_t environment_top()
+{
+ return ARR_LEN(environment_stack);
+}
+
+
+