//===- AsmWriterInst.h - Classes encapsulating a printable inst -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These classes implement a parser for assembly strings.  The parser splits
// the string into operands, which can be literal strings (the constant bits of
// the string), actual operands (i.e., operands from the MachineInstr), and
// dynamically-generated text, specified by raw C++ code.
//
//===----------------------------------------------------------------------===//

#ifndef ASMWRITER_INST_H
#define ASMWRITER_INST_H

#include <string>
#include <vector>

namespace llvm {
  class CodeGenInstruction;
  class Record;

  struct AsmWriterOperand {
    enum OpType {
      // Output this text surrounded by quotes to the asm.
      isLiteralTextOperand,
      // This is the name of a routine to call to print the operand.
      isMachineInstrOperand,
      // Output this text verbatim to the asm writer.  It is code that
      // will output some text to the asm.
      isLiteralStatementOperand
    } OperandType;

    /// Str - For isLiteralTextOperand, this IS the literal text.  For
    /// isMachineInstrOperand, this is the PrinterMethodName for the operand..
    /// For isLiteralStatementOperand, this is the code to insert verbatim
    /// into the asm writer.
    std::string Str;

    /// CGIOpNo - For isMachineInstrOperand, this is the index of the operand in
    /// the CodeGenInstruction.
    unsigned CGIOpNo;

    /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
    /// machine instruction.
    unsigned MIOpNo;

    /// MiModifier - For isMachineInstrOperand, this is the modifier string for
    /// an operand, specified with syntax like ${opname:modifier}.
    std::string MiModifier;

    // To make VS STL happy
    AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}

    AsmWriterOperand(const std::string &LitStr,
                     OpType op = isLiteralTextOperand)
    : OperandType(op), Str(LitStr) {}

    AsmWriterOperand(const std::string &Printer,
                     unsigned _CGIOpNo,
                     unsigned _MIOpNo,
                     const std::string &Modifier,
                     OpType op = isMachineInstrOperand)
    : OperandType(op), Str(Printer), CGIOpNo(_CGIOpNo), MIOpNo(_MIOpNo),
    MiModifier(Modifier) {}

    bool operator!=(const AsmWriterOperand &Other) const {
      if (OperandType != Other.OperandType || Str != Other.Str) return true;
      if (OperandType == isMachineInstrOperand)
        return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
      return false;
    }
    bool operator==(const AsmWriterOperand &Other) const {
      return !operator!=(Other);
    }

    /// getCode - Return the code that prints this operand.
    std::string getCode() const;
  };

  class AsmWriterInst {
  public:
    std::vector<AsmWriterOperand> Operands;
    const CodeGenInstruction *CGI;

    AsmWriterInst(const CodeGenInstruction &CGI,
                  unsigned Variant,
                  int FirstOperandColumn,
                  int OperandSpacing);

    /// MatchesAllButOneOp - If this instruction is exactly identical to the
    /// specified instruction except for one differing operand, return the
    /// differing operand number.  Otherwise return ~0.
    unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;

  private:
    void AddLiteralString(const std::string &Str) {
      // If the last operand was already a literal text string, append this to
      // it, otherwise add a new operand.
      if (!Operands.empty() &&
          Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
        Operands.back().Str.append(Str);
      else
        Operands.push_back(AsmWriterOperand(Str));
    }
  };
}

#endif
