/* $Id: scope.h,v 1.39 2009/01/27 15:40:22 potyra Exp $ 
 *
 * Copyright (C) 2007-2009 FAUcc Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#ifndef __SCOPE_H_INCLUDED
#define __SCOPE_H_INCLUDED

#include "declaration.h"
#include "label.h"

struct scope {
	struct scope *prev;
	struct scope *next;

	enum scope_type {
		SCOPE_NONE = 0,
		SCOPE_GLOBAL,
		SCOPE_FUNCTION,
		SCOPE_PARAMETER,
		SCOPE_BLOCK,
		SCOPE_STRUCT,
		SCOPE_UNION,
		SCOPE_ENUM,
	} type;

	struct scope *parent;
	struct scope *child_first;
	struct scope *child_last;

	struct declaration *function;

	struct declaration *declaration_first;
	struct declaration *declaration_last;

	struct label *label_first;
	struct label *label_last;
};

extern struct scope *scope_current;

extern int
scope_lookup_one(struct scope *scope, const char *name,
		struct declaration **dorp);
extern int
scope_lookup(struct scope *scope, const char *name,
		struct declaration **dorp);
extern int
scope_lookup_current(const char *name,
		struct declaration **dorp);

extern int
scope_lookup_structunionenum(
	struct scope *scope,
	enum type_type type,
	const char *name,
	struct type **tsp
);

extern void
scope_struct_begin(const char *identifier);
extern void
scope_struct_end(void);
extern void
scope_union_begin(const char *identifier);
extern void
scope_union_end(void);
extern void
scope_enum_begin(const char *identifier);
extern void
scope_enum_add(const char *identifier, unsigned int val);
extern void
scope_enum_end(void);
extern void
scope_parameter_begin(void);
extern void
scope_parameter_end(struct declaration *first, struct declaration *last);
extern void
scope_block_begin(void);
extern void
scope_block_end(struct stmt *s);
extern void
scope_function_begin(struct type *ts, struct declaration *dor);
extern struct label *
scope_function_label_get(const char *identifier);
extern void
scope_function_end(struct stmt *s);
extern void
scope_declaration_prepend_first(struct scope *scope, struct declaration *nd);
extern void
scope_declaration_prepend(struct scope *scope,
		struct declaration *od, struct declaration *nd);
extern void
scope_declaration_append(struct scope *scope, struct declaration *dion);
extern void
scope_asm_add(unsigned int len, const char *code);
extern void
scope_file_begin(void);
extern void
scope_file_end(struct scope **scopep);

#endif /* __SCOPE_H_INCLUDED */
