//===- Assignment.cpp -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "mcld/Script/Assignment.h"

#include "mcld/LinkerScript.h"
#include "mcld/Module.h"
#include "mcld/LD/LDSection.h"
#include "mcld/LD/SectionData.h"
#include "mcld/Script/Operand.h"
#include "mcld/Script/Operator.h"
#include "mcld/Script/RpnEvaluator.h"
#include "mcld/Script/RpnExpr.h"
#include "mcld/Support/raw_ostream.h"

#include <llvm/Support/Casting.h>

#include <cassert>

namespace mcld {

//===----------------------------------------------------------------------===//
// Assignment
//===----------------------------------------------------------------------===//
Assignment::Assignment(Level pLevel,
                       Type pType,
                       SymOperand& pSymbol,
                       RpnExpr& pRpnExpr)
    : ScriptCommand(ScriptCommand::ASSIGNMENT),
      m_Level(pLevel),
      m_Type(pType),
      m_Symbol(pSymbol),
      m_RpnExpr(pRpnExpr) {
}

Assignment::~Assignment() {
}

Assignment& Assignment::operator=(const Assignment& pAssignment) {
  return *this;
}

void Assignment::dump() const {
  switch (type()) {
    case DEFAULT:
      break;
    case HIDDEN:
      mcld::outs() << "HIDDEN ( ";
      break;
    case PROVIDE:
      mcld::outs() << "PROVIDE ( ";
      break;
    case PROVIDE_HIDDEN:
      mcld::outs() << "PROVIDE_HIDDEN ( ";
      break;
    default:
      break;
  }

  m_Symbol.dump();

  mcld::outs() << " = ";

  m_RpnExpr.dump();

  if (type() != DEFAULT)
    mcld::outs() << " )";

  mcld::outs() << ";\n";
}

void Assignment::activate(Module& pModule) {
  bool isLhsDot = m_Symbol.isDot();
  LinkerScript& script = pModule.getScript();
  switch (m_Level) {
    case OUTSIDE_SECTIONS:
      assert(!isLhsDot);
      script.assignments().push_back(std::make_pair(nullptr, *this));
      break;

    case OUTPUT_SECTION: {
      bool hasDotInRhs = m_RpnExpr.hasDot();
      SectionMap::reference out = script.sectionMap().back();
      if (hasDotInRhs) {
        if (!isLhsDot && out->dotAssignments().empty()) {
          // . = ADDR ( `prev_output_sect' ) + SIZEOF ( `prev_output_sect' )
          SectionMap::iterator prev =
              script.sectionMap().begin() + script.sectionMap().size() - 2;
          Assignment assign(OUTPUT_SECTION,
                            HIDDEN,
                            *SymOperand::create("."),
                            *RpnExpr::buildHelperExpr(prev));
          out->dotAssignments().push_back(assign);
        }

        if (!out->dotAssignments().empty()) {
          Assignment& prevDotAssign = out->dotAssignments().back();
          // If this is the 1st explicit assignment that includes both lhs dot
          // and
          // rhs dot, then because of possible orphan sections, we are unable to
          // substitute the rhs dot now.
          if (!isLhsDot || prevDotAssign.type() == DEFAULT) {
            for (RpnExpr::iterator it = m_RpnExpr.begin(), ie = m_RpnExpr.end();
                 it != ie;
                 ++it) {
              // substitute the rhs dot with the appropriate helper expr
              if ((*it)->kind() == ExprToken::OPERAND &&
                  llvm::cast<Operand>(*it)->isDot()) {
                *it = &(prevDotAssign.symbol());
              }
            }  // for each expression token
          }
        }
      }

      if (isLhsDot) {
        out->dotAssignments().push_back(*this);
      } else {
        script.assignments().push_back(std::make_pair(nullptr, *this));
      }
      break;
    }

    case INPUT_SECTION: {
      bool hasDotInRhs = m_RpnExpr.hasDot();
      SectionMap::Output::reference in = script.sectionMap().back()->back();
      if (hasDotInRhs) {
        if (in->dotAssignments().empty()) {
          // . = `frag'
          RpnExpr* expr = RpnExpr::buildHelperExpr(
              in->getSection()->getSectionData()->front());
          Assignment assign(
              INPUT_SECTION, HIDDEN, *SymOperand::create("."), *expr);
          in->dotAssignments().push_back(std::make_pair(nullptr, assign));
        }

        Assignment& prevDotAssign = in->dotAssignments().back().second;
        for (RpnExpr::iterator it = m_RpnExpr.begin(), ie = m_RpnExpr.end();
             it != ie;
             ++it) {
          // substitute the rhs dot with the appropriate helper expr
          if ((*it)->kind() == ExprToken::OPERAND &&
              llvm::cast<Operand>(*it)->isDot()) {
            *it = &(prevDotAssign.symbol());
          }
        }  // end of for
      }

      if (isLhsDot) {
        in->dotAssignments().push_back(std::make_pair(
            in->getSection()->getSectionData()->front().getNextNode(), *this));
      } else {
        script.assignments().push_back(std::make_pair(nullptr, *this));
      }
      break;
    }
  }  // end of switch
}

bool Assignment::assign(RpnEvaluator& pEvaluator) {
  uint64_t result = 0;
  bool success = pEvaluator.eval(m_RpnExpr, result);
  if (success)
    m_Symbol.setValue(result);
  return success;
}

}  // namespace mcld
