/* $Id$ 
 * CheckAccessMode: visitor to check if reading/writing data is permitted
 * via in,inout,out access modes.
 *
 * Copyright (C) 2008-2009 FAUmachine 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 __CHECK_ACCESS_MODES_HPP_INCLUDED
#define __CHECK_ACCESS_MODES_HPP_INCLUDED

#include "frontend/visitor/TopDownVisitor.hpp"
#include "frontend/ast/ValDeclaration.hpp"

namespace ast {

//! check if reading/writing to a data/signal/constant is permitted.
/** Dependencies:
 *  - ResolveTypes
 *  - NormalizeAssocs
 */
class CheckAccessMode : public TopDownVisitor {
public:
	//! c'tor
	CheckAccessMode() : accessMode(ValDeclaration::MODE_IN), 
			    isForeign(false) {}

private:
	/** visit a SimpleName
         *  @param node node that get's visited.
         */
	virtual void visit(SimpleName &node);

	/** Visit a VarAssignStat
	 *  @param node VarAssignStat node that get's visited.
	 */
	virtual void visit(VarAssignStat &node);

	/** Visit a SigAssignStat
	 *  @param node SigAssignStat node that get's visited.
	 */
	virtual void visit(SigAssignStat &node);

	/** Visit a CompInstStat node.
	 *  @param node CompInstStat node that get's visited.
	 */
	virtual void visit(CompInstStat& node);

	/** Visit a Subscript node.
	 *  @param node Subscript node that get's visited.
	 */
	virtual void visit(Subscript &node);

	/** Visit a Slice node.
	 *  @param node Slice node that get's visited.
	 */
	virtual void visit(Slice &node);

	/** Visit an Aggregate node.
	 *  @param node Aggregate node that get's visited.
	 */
	virtual void visit(Aggregate &node);

	/** visit a ConstInteger
         *  @param node node that get's visited.
         */
	virtual void visit(ConstInteger &node);

	/** visit a ConstReal
         *  @param node node that get's visited.
         */
	virtual void visit(ConstReal &node);

	/** visit a ConstArray
         *  @param node node that get's visited.
         */
	virtual void visit(ConstArray &node);

	/** Visit a FunctionCall.
	 *  @param node FunctionCall node that get's visited.
	 */
	virtual void visit(FunctionCall &node);

	/** Visit a ProcCallStat
	 *  @param node ReturnStat node that get's visited.
	 */
	virtual void visit(ProcCallStat &node);

	/** Visit an Entity declaration.
	 *  @param node Entity Declaration node that get's visited.
	 */
	virtual void visit(Entity &node);

	/** process a function call or procedure call.
	 *  @param args argument list
	 *  @param node corresponding Callable definition.
	 */
	void 
	processCall(
		std::list<AssociationElement *> &args, 
		const Callable &node
	);

	//! Process a generic Callable.
        /** This function will get called for each Callable (or class
         *  derived from Callable) that get's visited.
         *
         *  @param node Callable instance.
         */
	virtual void process(Callable &node);

	/** process a constant leaf node.
	 *  Will report an error, if the node is to be accessed
	 *  via INOUT or OUT.
	 *  @param node leaf node.
	 */
	void processConst(const Expression &node) const;

	//! how is the current variable accessed?
	ValDeclaration::Mode accessMode;

	//! actual designator of a foreign CompInstStat/subprogram call?
	bool isForeign;
};

}; /* namespace ast */

#endif /* __CHECK_ACCESS_MODES_HPP_INCLUDED */
