/* ILEngineer - Crummy .NET Decompiler
 * Copyright (C) 2001-2002  Jay Freeman (saurik)
*/

/*
 *        Redistribution and use in source and binary
 * forms, with or without modification, are permitted
 * provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer in the documentation
 *    and/or other materials provided with the
 *    distribution.
 * 3. The name of the author may not be used to endorse
 *    or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include "ilengineer/Block.h"
#include "ilengineer/Ops/MSIL/Duplicate.h"
#include "ilengineer/Ops/MSIL/LoadField.h"
#include "ilengineer/Ops/MSIL/StoreField.h"

#include "ilengineer/ilengineer.h"

namespace ILEngineer {
namespace Blocks {
	class ILENGINEER_API Method : public Block {
	  protected:
		const Metallurgy::Module *m_Import;
		const Metallurgy::Method *method;
		Metallurgy::Signature *m_Locals;
		bool m_Native;

	  public:
		Method(const Metallurgy::Method *method);

		virtual ~Method();

		/*template <class From, class To> void OptimizeStarEqualField(Ops::MSIL::StoreField *store, From *from, Operation * &where) {
			if (typeid(*from->getValue1()) == typeid(Ops::MSIL::LoadField)) {
				Ops::MSIL::LoadField *field(dynamic_cast<Ops::MSIL::LoadField *>(from->getValue1()));
				if (field->getMember() == store->getMember() &&
					typeid(*field->getObj()) == typeid(Ops::MSIL::Duplicate) &&
					dynamic_cast<Ops::MSIL::Duplicate *>(field->getObj())->getValue() == 
					dynamic_cast<Ops::MSIL::Duplicate *>(store->getObj())->getValue())
				{
					where = new To(m_Method, from, store);
					delete store;
				}
			}
		}*/

		void UpdateTargets();
		void OptimizeGeneral();

		const Metallurgy::Module *getImport();
		const Metallurgy::Method &getMethodDef();
	};
} }