// $Id: ID.h,v 1.20 2003/08/31 00:38:11 vern Exp $
//
// Copyright (c) 1995, 1996, 1997, 1998, 1999, 2002
//      The Regents of the University of California.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that: (1) source code distributions
// retain the above copyright notice and this paragraph in its entirety, (2)
// distributions including binary code include the above copyright notice and
// this paragraph in its entirety in the documentation or other materials
// provided with the distribution, and (3) all advertising materials mentioning
// features or use of this software display the following acknowledgement:
// ``This product includes software developed by the University of California,
// Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
// the University nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef id_h
#define id_h

#include "Type.h"
#include "Attr.h"
#include <string>

class Val;

typedef enum { INIT_NONE, INIT_FULL, INIT_EXTRA, INIT_REMOVE, } init_class;
typedef enum { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL } IDScope;

class ID : public BroObj {
public:
	ID(char* name, IDScope arg_scope, bool arg_is_export);
	~ID();

	const char* Name() const	{ return name; }

	int Scope() const		{ return scope; }
	bool IsGlobal() const           { return scope != SCOPE_FUNCTION; }
	bool IsExport() const           { return is_export; }

	string ModuleName() const;

	void SetType(BroType* t)	{ Unref(type); type = t; }
	BroType* Type()			{ return type; }

	void MakeType()			{ is_type = 1; }
	BroType* AsType()		{ return is_type ? Type() : 0; }

	void SetVal(Val* v);
	void SetVal(Val* v, init_class c);
	void SetVal(Expr* ev, init_class c);

	int HasVal() const		{ return val != 0; }
	Val* ID_Val()			{ return val; }

	void SetConst()			{ is_const = 1; }
	int IsConst() const		{ return is_const; }

	void SetEnumConst()		{ is_enum_const = 1; }
	int IsEnumConst() const		{ return is_enum_const; }

	void SetOffset(int arg_offset)	{ offset = arg_offset; }
	int Offset() const		{ return offset; }

	int IsRedefinable() const	{ return FindAttr(ATTR_REDEF) != 0; }

	void SetAttrs(Attributes* attr);
	void AddAttrs(Attributes* attr);
	Attributes* Attrs() const	{ return attrs; }

	Attr* FindAttr(attr_tag t) const
		{ return attrs ? attrs->FindAttr(t) : 0; }

	void Error(const char* msg, const BroObj* o2 = 0);

	void Describe(ODesc* d) const;

protected:
	void CheckAttr(Attr* attr);
	void EvalFunc(Expr* ef, Expr* ev);

	char* name;
	IDScope scope;
	bool is_export;
	BroType* type;
	int is_const, is_enum_const, is_type;
	int offset;
	Val* val;
	Attributes* attrs;
};

#endif
