//===- TranslateToCpp.cpp - Translating to C++ calls ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/EmitC/IR/EmitCInterfaces.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/IR/Value.h"
#include "mlir/Support/IndentedOstream.h"
#include "mlir/Support/LLVM.h"
#include "mlir/Target/Cpp/CppEmitter.h"
#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormatVariadic.h"
#include <stack>

#define DEBUG_TYPE "translate-to-cpp"

using namespace mlir;
using namespace mlir::emitc;
using llvm::formatv;

/// Convenience functions to produce interleaved output with functions returning
/// a LogicalResult. This is different than those in STLExtras as functions used
/// on each element doesn't return a string.
template <typename ForwardIterator, typename UnaryFunctor,
          typename NullaryFunctor>
static inline LogicalResult
interleaveWithError(ForwardIterator begin, ForwardIterator end,
                    UnaryFunctor eachFn, NullaryFunctor betweenFn) {
  if (begin == end)
    return success();
  if (failed(eachFn(*begin)))
    return failure();
  ++begin;
  for (; begin != end; ++begin) {
    betweenFn();
    if (failed(eachFn(*begin)))
      return failure();
  }
  return success();
}

template <typename Container, typename UnaryFunctor, typename NullaryFunctor>
static inline LogicalResult interleaveWithError(const Container &c,
                                                UnaryFunctor eachFn,
                                                NullaryFunctor betweenFn) {
  return interleaveWithError(c.begin(), c.end(), eachFn, betweenFn);
}

template <typename Container, typename UnaryFunctor>
static inline LogicalResult interleaveCommaWithError(const Container &c,
                                                     raw_ostream &os,
                                                     UnaryFunctor eachFn) {
  return interleaveWithError(c.begin(), c.end(), eachFn, [&]() { os << ", "; });
}

/// Return the precedence of a operator as an integer, higher values
/// imply higher precedence.
static FailureOr<int> getOperatorPrecedence(Operation *operation) {
  return llvm::TypeSwitch<Operation *, FailureOr<int>>(operation)
      .Case([&](emitc::AddressOfOp op) { return 15; })
      .Case([&](emitc::AddOp op) { return 12; })
      .Case([&](emitc::ApplyOp op) { return 15; })
      .Case([&](emitc::BitwiseAndOp op) { return 7; })
      .Case([&](emitc::BitwiseLeftShiftOp op) { return 11; })
      .Case([&](emitc::BitwiseNotOp op) { return 15; })
      .Case([&](emitc::BitwiseOrOp op) { return 5; })
      .Case([&](emitc::BitwiseRightShiftOp op) { return 11; })
      .Case([&](emitc::BitwiseXorOp op) { return 6; })
      .Case([&](emitc::CallOp op) { return 16; })
      .Case([&](emitc::CallOpaqueOp op) { return 16; })
      .Case([&](emitc::CastOp op) { return 15; })
      .Case([&](emitc::CmpOp op) -> FailureOr<int> {
        switch (op.getPredicate()) {
        case emitc::CmpPredicate::eq:
        case emitc::CmpPredicate::ne:
          return 8;
        case emitc::CmpPredicate::lt:
        case emitc::CmpPredicate::le:
        case emitc::CmpPredicate::gt:
        case emitc::CmpPredicate::ge:
          return 9;
        case emitc::CmpPredicate::three_way:
          return 10;
        }
        return op->emitError("unsupported cmp predicate");
      })
      .Case([&](emitc::ConditionalOp op) { return 2; })
      .Case([&](emitc::ConstantOp op) { return 17; })
      .Case([&](emitc::DereferenceOp op) { return 15; })
      .Case([&](emitc::DivOp op) { return 13; })
      .Case([&](emitc::GetGlobalOp op) { return 18; })
      .Case([&](emitc::LiteralOp op) { return 18; })
      .Case([&](emitc::LoadOp op) { return 16; })
      .Case([&](emitc::LogicalAndOp op) { return 4; })
      .Case([&](emitc::LogicalNotOp op) { return 15; })
      .Case([&](emitc::LogicalOrOp op) { return 3; })
      .Case([&](emitc::MemberOfPtrOp op) { return 17; })
      .Case([&](emitc::MemberOp op) { return 17; })
      .Case([&](emitc::MulOp op) { return 13; })
      .Case([&](emitc::RemOp op) { return 13; })
      .Case([&](emitc::SubOp op) { return 12; })
      .Case([&](emitc::SubscriptOp op) { return 17; })
      .Case([&](emitc::UnaryMinusOp op) { return 15; })
      .Case([&](emitc::UnaryPlusOp op) { return 15; })
      .Default([](auto op) { return op->emitError("unsupported operation"); });
}

static bool shouldBeInlined(Operation *op);

namespace {
/// Emitter that uses dialect specific emitters to emit C++ code.
struct CppEmitter {
  explicit CppEmitter(raw_ostream &os, bool declareVariablesAtTop,
                      StringRef fileId);

  /// Emits attribute or returns failure.
  LogicalResult emitAttribute(Location loc, Attribute attr);

  /// Emits operation 'op' with/without training semicolon or returns failure.
  ///
  /// For operations that should never be followed by a semicolon, like ForOp,
  /// the `trailingSemicolon` argument is ignored and a semicolon is not
  /// emitted.
  LogicalResult emitOperation(Operation &op, bool trailingSemicolon);

  /// Emits type 'type' or returns failure.
  LogicalResult emitType(Location loc, Type type);

  /// Emits array of types as a std::tuple of the emitted types.
  /// - emits void for an empty array;
  /// - emits the type of the only element for arrays of size one;
  /// - emits a std::tuple otherwise;
  LogicalResult emitTypes(Location loc, ArrayRef<Type> types);

  /// Emits array of types as a std::tuple of the emitted types independently of
  /// the array size.
  LogicalResult emitTupleType(Location loc, ArrayRef<Type> types);

  /// Emits an assignment for a variable which has been declared previously.
  LogicalResult emitVariableAssignment(OpResult result);

  /// Emits a variable declaration for a result of an operation.
  LogicalResult emitVariableDeclaration(OpResult result,
                                        bool trailingSemicolon);

  /// Emits a declaration of a variable with the given type and name.
  LogicalResult emitVariableDeclaration(Location loc, Type type,
                                        StringRef name);

  /// Emits the variable declaration and assignment prefix for 'op'.
  /// - emits separate variable followed by std::tie for multi-valued operation;
  /// - emits single type followed by variable for single result;
  /// - emits nothing if no value produced by op;
  /// Emits final '=' operator where a type is produced. Returns failure if
  /// any result type could not be converted.
  LogicalResult emitAssignPrefix(Operation &op);

  /// Emits a global variable declaration or definition.
  LogicalResult emitGlobalVariable(GlobalOp op);

  /// Emits a label for the block.
  LogicalResult emitLabel(Block &block);

  /// Emits the operands and atttributes of the operation. All operands are
  /// emitted first and then all attributes in alphabetical order.
  LogicalResult emitOperandsAndAttributes(Operation &op,
                                          ArrayRef<StringRef> exclude = {});

  /// Emits the operands of the operation. All operands are emitted in order.
  LogicalResult emitOperands(Operation &op);

  /// Emits value as an operand of some operation. Unless \p isInBrackets is
  /// true, operands emitted as sub-expressions will be parenthesized if needed
  /// in order to enforce correct evaluation based on precedence and
  /// associativity.
  LogicalResult emitOperand(Value value, bool isInBrackets = false);

  /// Emit an expression as a C expression.
  LogicalResult emitExpression(Operation *op);

  /// Return the existing or a new name for a Value.
  StringRef getOrCreateName(Value val);

  /// Return the existing or a new name for a loop induction variable of an
  /// emitc::ForOp.
  StringRef getOrCreateInductionVarName(Value val);

  /// Return the existing or a new label of a Block.
  StringRef getOrCreateName(Block &block);

  LogicalResult emitInlinedExpression(Value value);

  /// Whether to map an mlir integer to a unsigned integer in C++.
  bool shouldMapToUnsigned(IntegerType::SignednessSemantics val);

  /// Abstract RAII helper function to manage entering/exiting C++ scopes.
  struct Scope {
    ~Scope() { emitter.labelInScopeCount.pop(); }

  private:
    llvm::ScopedHashTableScope<Value, std::string> valueMapperScope;
    llvm::ScopedHashTableScope<Block *, std::string> blockMapperScope;

  protected:
    Scope(CppEmitter &emitter)
        : valueMapperScope(emitter.valueMapper),
          blockMapperScope(emitter.blockMapper), emitter(emitter) {
      emitter.labelInScopeCount.push(emitter.labelInScopeCount.top());
    }
    CppEmitter &emitter;
  };

  /// RAII helper function to manage entering/exiting functions, while re-using
  /// value names.
  struct FunctionScope : Scope {
    FunctionScope(CppEmitter &emitter) : Scope(emitter) {
      // Re-use value names.
      emitter.resetValueCounter();
    }
  };

  /// RAII helper function to manage entering/exiting emitc::forOp loops and
  /// handle induction variable naming.
  struct LoopScope : Scope {
    LoopScope(CppEmitter &emitter) : Scope(emitter) {
      emitter.increaseLoopNestingLevel();
    }
    ~LoopScope() { emitter.decreaseLoopNestingLevel(); }
  };

  /// Returns wether the Value is assigned to a C++ variable in the scope.
  bool hasValueInScope(Value val);

  // Returns whether a label is assigned to the block.
  bool hasBlockLabel(Block &block);

  /// Returns the output stream.
  raw_indented_ostream &ostream() { return os; };

  /// Returns if all variables for op results and basic block arguments need to
  /// be declared at the beginning of a function.
  bool shouldDeclareVariablesAtTop() { return declareVariablesAtTop; };

  /// Returns whether this file op should be emitted
  bool shouldEmitFile(FileOp file) {
    return !fileId.empty() && file.getId() == fileId;
  }

  /// Is expression currently being emitted.
  bool isEmittingExpression() { return !emittedExpressionPrecedence.empty(); }

  /// Determine whether given value is part of the expression potentially being
  /// emitted.
  bool isPartOfCurrentExpression(Value value) {
    Operation *def = value.getDefiningOp();
    return def ? isPartOfCurrentExpression(def) : false;
  }

  /// Determine whether given operation is part of the expression potentially
  /// being emitted.
  bool isPartOfCurrentExpression(Operation *def) {
    return isEmittingExpression() && shouldBeInlined(def);
  };

  // Resets the value counter to 0.
  void resetValueCounter();

  // Increases the loop nesting level by 1.
  void increaseLoopNestingLevel();

  // Decreases the loop nesting level by 1.
  void decreaseLoopNestingLevel();

private:
  using ValueMapper = llvm::ScopedHashTable<Value, std::string>;
  using BlockMapper = llvm::ScopedHashTable<Block *, std::string>;

  /// Output stream to emit to.
  raw_indented_ostream os;

  /// Boolean to enforce that all variables for op results and block
  /// arguments are declared at the beginning of the function. This also
  /// includes results from ops located in nested regions.
  bool declareVariablesAtTop;

  /// Only emit file ops whos id matches this value.
  std::string fileId;

  /// Map from value to name of C++ variable that contain the name.
  ValueMapper valueMapper;

  /// Map from block to name of C++ label.
  BlockMapper blockMapper;

  /// Default values representing outermost scope.
  llvm::ScopedHashTableScope<Value, std::string> defaultValueMapperScope;
  llvm::ScopedHashTableScope<Block *, std::string> defaultBlockMapperScope;

  std::stack<int64_t> labelInScopeCount;

  /// Keeps track of the amount of nested loops the emitter currently operates
  /// in.
  uint64_t loopNestingLevel{0};

  /// Emitter-level count of created values to enable unique identifiers.
  unsigned int valueCount{0};

  /// State of the current expression being emitted.
  SmallVector<int> emittedExpressionPrecedence;

  void pushExpressionPrecedence(int precedence) {
    emittedExpressionPrecedence.push_back(precedence);
  }
  void popExpressionPrecedence() { emittedExpressionPrecedence.pop_back(); }
  static int lowestPrecedence() { return 0; }
  int getExpressionPrecedence() {
    if (emittedExpressionPrecedence.empty())
      return lowestPrecedence();
    return emittedExpressionPrecedence.back();
  }
};
} // namespace

/// Determine whether operation \p op should be emitted inline, i.e.
/// as part of its user. This function recommends inlining of any expressions
/// that can be inlined unless it is used by another expression, under the
/// assumption that  any expression fusion/re-materialization was taken care of
/// by transformations run by the backend.
static bool shouldBeInlined(Operation *op) {
  // CExpression operations are inlined if and only if they are marked as
  // always-inline or reside in an ExpressionOp.
  if (auto cExpression = dyn_cast<CExpressionInterface>(op))
    return cExpression.alwaysInline() || isa<ExpressionOp>(op->getParentOp());

  // Only other inlinable operation is ExpressionOp itself.
  ExpressionOp expressionOp = dyn_cast<ExpressionOp>(op);
  if (!expressionOp)
    return false;

  // Inline if the root operation is an always-inline CExpression.
  if (cast<CExpressionInterface>(expressionOp.getRootOp()).alwaysInline())
    return true;

  // Do not inline if expression is marked as such.
  if (expressionOp.getDoNotInline())
    return false;

  // Do not inline expressions with multiple uses.
  Value result = expressionOp.getResult();
  if (!result.hasOneUse())
    return false;

  Operation *user = *result.getUsers().begin();

  // Do not inline expressions used by other expressions or by ops with the
  // CExpressionInterface. If this was intended, the user could have been merged
  // into the expression op.
  if (isa<emitc::ExpressionOp, emitc::CExpressionInterface>(*user))
    return false;

  // Expressions with no side-effects can safely be inlined.
  if (!expressionOp.hasSideEffects())
    return true;

  // Expressions with side-effects can be only inlined if side-effect ordering
  // in the program is provably retained.

  // Require the user to immediately follow the expression.
  if (++Block::iterator(expressionOp) != Block::iterator(user))
    return false;

  // These single-operand ops are safe.
  if (isa<emitc::IfOp, emitc::SwitchOp, emitc::ReturnOp>(user))
    return true;

  // For assignment look for specific cases to inline as evaluation order of
  // its lvalue and rvalue is undefined in C.
  if (auto assignOp = dyn_cast<emitc::AssignOp>(user)) {
    // Inline if this assignment is of the form `<var> = <expression>`.
    if (expressionOp.getResult() == assignOp.getValue() &&
        isa_and_present<VariableOp>(assignOp.getVar().getDefiningOp()))
      return true;
  }

  return false;
}

/// Helper function to check if a value traces back to a const global.
/// Handles direct GetGlobalOp and GetGlobalOp through one or more SubscriptOps.
/// Returns the GlobalOp if found and it has const_specifier, nullptr otherwise.
static emitc::GlobalOp getConstGlobal(Value value, Operation *fromOp) {
  while (auto subscriptOp = value.getDefiningOp<emitc::SubscriptOp>()) {
    value = subscriptOp.getValue();
  }

  auto getGlobalOp = value.getDefiningOp<emitc::GetGlobalOp>();
  if (!getGlobalOp)
    return nullptr;

  // Find the nearest symbol table to check whether the global is const.
  auto globalOp = SymbolTable::lookupNearestSymbolFrom<emitc::GlobalOp>(
      fromOp, getGlobalOp.getNameAttr());

  if (globalOp && globalOp.getConstSpecifier())
    return globalOp;

  return nullptr;
}

/// Emit address-of with a cast to strip const qualification.
/// Produces: (ResultType)(&operand)
static LogicalResult emitAddressOfWithConstCast(CppEmitter &emitter,
                                                Operation &op, Value operand) {
  raw_ostream &os = emitter.ostream();
  os << "(";
  if (failed(emitter.emitType(op.getLoc(), op.getResult(0).getType())))
    return failure();
  os << ")(&";
  if (failed(emitter.emitOperand(operand)))
    return failure();
  os << ")";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::DereferenceOp dereferenceOp) {
  raw_ostream &os = emitter.ostream();
  Operation &op = *dereferenceOp.getOperation();

  if (failed(emitter.emitAssignPrefix(op)))
    return failure();
  os << "*";
  return emitter.emitOperand(dereferenceOp.getPointer());
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::GetFieldOp getFieldOp) {
  if (!emitter.isPartOfCurrentExpression(getFieldOp.getOperation()))
    return success();

  emitter.ostream() << getFieldOp.getFieldName();
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::GetGlobalOp getGlobalOp) {
  if (!emitter.isPartOfCurrentExpression(getGlobalOp.getOperation()))
    return success();

  emitter.ostream() << getGlobalOp.getName();
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::LiteralOp literalOp) {
  if (!emitter.isPartOfCurrentExpression(literalOp.getOperation()))
    return success();

  emitter.ostream() << literalOp.getValue();
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::MemberOp memberOp) {
  if (!emitter.isPartOfCurrentExpression(memberOp.getOperation()))
    return success();

  if (failed(emitter.emitOperand(memberOp.getOperand())))
    return failure();
  emitter.ostream() << "." << memberOp.getMember();
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::MemberOfPtrOp memberOfPtrOp) {
  if (!emitter.isPartOfCurrentExpression(memberOfPtrOp.getOperation()))
    return success();

  if (failed(emitter.emitOperand(memberOfPtrOp.getOperand())))
    return failure();
  emitter.ostream() << "->" << memberOfPtrOp.getMember();
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::SubscriptOp subscriptOp) {
  if (!emitter.isPartOfCurrentExpression(subscriptOp.getOperation())) {
    return success();
  }

  raw_ostream &os = emitter.ostream();
  if (failed(emitter.emitOperand(subscriptOp.getValue())))
    return failure();
  for (auto index : subscriptOp.getIndices()) {
    os << "[";
    if (failed(emitter.emitOperand(index, /*isInBrackets=*/true)))
      return failure();
    os << "]";
  }
  return success();
}

static LogicalResult printConstantOp(CppEmitter &emitter, Operation *operation,
                                     Attribute value) {
  OpResult result = operation->getResult(0);

  // Only emit an assignment as the variable was already declared when printing
  // the FuncOp.
  if (emitter.shouldDeclareVariablesAtTop()) {
    // Skip the assignment if the emitc.constant has no value.
    if (auto oAttr = dyn_cast<emitc::OpaqueAttr>(value)) {
      if (oAttr.getValue().empty())
        return success();
    }

    if (failed(emitter.emitVariableAssignment(result)))
      return failure();
    return emitter.emitAttribute(operation->getLoc(), value);
  }

  // Emit a variable declaration for an emitc.constant op without value.
  if (auto oAttr = dyn_cast<emitc::OpaqueAttr>(value)) {
    if (oAttr.getValue().empty())
      // The semicolon gets printed by the emitOperation function.
      return emitter.emitVariableDeclaration(result,
                                             /*trailingSemicolon=*/false);
  }

  // Emit a variable declaration.
  if (failed(emitter.emitAssignPrefix(*operation)))
    return failure();
  return emitter.emitAttribute(operation->getLoc(), value);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::AddressOfOp addressOfOp) {
  raw_ostream &os = emitter.ostream();
  Operation &op = *addressOfOp.getOperation();

  if (failed(emitter.emitAssignPrefix(op)))
    return failure();

  Value operand = addressOfOp.getReference();

  // Check if we're taking address of a const global.
  if (getConstGlobal(operand, &op))
    return emitAddressOfWithConstCast(emitter, op, operand);

  os << "&";
  return emitter.emitOperand(operand);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::ConstantOp constantOp) {
  Operation *operation = constantOp.getOperation();
  Attribute value = constantOp.getValue();

  if (emitter.isPartOfCurrentExpression(operation))
    return emitter.emitAttribute(operation->getLoc(), value);

  return printConstantOp(emitter, operation, value);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::VariableOp variableOp) {
  Operation *operation = variableOp.getOperation();
  Attribute value = variableOp.getValue();

  return printConstantOp(emitter, operation, value);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::GlobalOp globalOp) {

  return emitter.emitGlobalVariable(globalOp);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::AssignOp assignOp) {
  if (failed(emitter.emitOperand(assignOp.getVar())))
    return failure();

  emitter.ostream() << " = ";

  return emitter.emitOperand(assignOp.getValue());
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::LoadOp loadOp) {
  if (failed(emitter.emitAssignPrefix(*loadOp)))
    return failure();

  return emitter.emitOperand(loadOp.getOperand());
}

static LogicalResult printBinaryOperation(CppEmitter &emitter,
                                          Operation *operation,
                                          StringRef binaryOperator) {
  raw_ostream &os = emitter.ostream();

  if (failed(emitter.emitAssignPrefix(*operation)))
    return failure();

  if (failed(emitter.emitOperand(operation->getOperand(0))))
    return failure();

  os << " " << binaryOperator << " ";

  if (failed(emitter.emitOperand(operation->getOperand(1))))
    return failure();

  return success();
}

static LogicalResult printUnaryOperation(CppEmitter &emitter,
                                         Operation *operation,
                                         StringRef unaryOperator) {
  raw_ostream &os = emitter.ostream();

  if (failed(emitter.emitAssignPrefix(*operation)))
    return failure();

  os << unaryOperator;

  if (failed(emitter.emitOperand(operation->getOperand(0))))
    return failure();

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::AddOp addOp) {
  Operation *operation = addOp.getOperation();

  return printBinaryOperation(emitter, operation, "+");
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::DivOp divOp) {
  Operation *operation = divOp.getOperation();

  return printBinaryOperation(emitter, operation, "/");
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::MulOp mulOp) {
  Operation *operation = mulOp.getOperation();

  return printBinaryOperation(emitter, operation, "*");
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::RemOp remOp) {
  Operation *operation = remOp.getOperation();

  return printBinaryOperation(emitter, operation, "%");
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::SubOp subOp) {
  Operation *operation = subOp.getOperation();

  return printBinaryOperation(emitter, operation, "-");
}

static LogicalResult emitSwitchCase(CppEmitter &emitter,
                                    raw_indented_ostream &os, Region &region) {
  for (Region::OpIterator iteratorOp = region.op_begin(), end = region.op_end();
       std::next(iteratorOp) != end; ++iteratorOp) {
    if (failed(emitter.emitOperation(*iteratorOp, /*trailingSemicolon=*/true)))
      return failure();
  }
  os << "break;\n";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::SwitchOp switchOp) {
  raw_indented_ostream &os = emitter.ostream();

  os << "switch (";
  if (failed(emitter.emitOperand(switchOp.getArg())))
    return failure();
  os << ") {";

  for (auto pair : llvm::zip(switchOp.getCases(), switchOp.getCaseRegions())) {
    os << "\ncase " << std::get<0>(pair) << ": {\n";
    os.indent();

    if (failed(emitSwitchCase(emitter, os, std::get<1>(pair))))
      return failure();

    os.unindent() << "}";
  }

  os << "\ndefault: {\n";
  os.indent();

  if (failed(emitSwitchCase(emitter, os, switchOp.getDefaultRegion())))
    return failure();

  os.unindent() << "}\n}";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::DoOp doOp) {
  raw_indented_ostream &os = emitter.ostream();

  os << "do {\n";
  os.indent();

  Block &bodyBlock = doOp.getBodyRegion().front();
  for (Operation &op : bodyBlock) {
    if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/true)))
      return failure();
  }

  os.unindent() << "} while (";

  Block &condBlock = doOp.getConditionRegion().front();
  auto condYield = cast<emitc::YieldOp>(condBlock.back());
  if (failed(emitter.emitExpression(
          cast<emitc::ExpressionOp>(condYield.getOperand(0).getDefiningOp()))))
    return failure();

  os << ");";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::CmpOp cmpOp) {
  Operation *operation = cmpOp.getOperation();

  StringRef binaryOperator;

  switch (cmpOp.getPredicate()) {
  case emitc::CmpPredicate::eq:
    binaryOperator = "==";
    break;
  case emitc::CmpPredicate::ne:
    binaryOperator = "!=";
    break;
  case emitc::CmpPredicate::lt:
    binaryOperator = "<";
    break;
  case emitc::CmpPredicate::le:
    binaryOperator = "<=";
    break;
  case emitc::CmpPredicate::gt:
    binaryOperator = ">";
    break;
  case emitc::CmpPredicate::ge:
    binaryOperator = ">=";
    break;
  case emitc::CmpPredicate::three_way:
    binaryOperator = "<=>";
    break;
  }

  return printBinaryOperation(emitter, operation, binaryOperator);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::ConditionalOp conditionalOp) {
  raw_ostream &os = emitter.ostream();

  if (failed(emitter.emitAssignPrefix(*conditionalOp)))
    return failure();

  if (failed(emitter.emitOperand(conditionalOp.getCondition())))
    return failure();

  os << " ? ";

  if (failed(emitter.emitOperand(conditionalOp.getTrueValue())))
    return failure();

  os << " : ";

  if (failed(emitter.emitOperand(conditionalOp.getFalseValue())))
    return failure();

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::VerbatimOp verbatimOp) {
  raw_ostream &os = emitter.ostream();

  FailureOr<SmallVector<ReplacementItem>> items =
      verbatimOp.parseFormatString();
  if (failed(items))
    return failure();

  auto fmtArg = verbatimOp.getFmtArgs().begin();

  for (ReplacementItem &item : *items) {
    if (auto *str = std::get_if<StringRef>(&item)) {
      os << *str;
    } else {
      if (failed(emitter.emitOperand(*fmtArg++)))
        return failure();
    }
  }

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    cf::BranchOp branchOp) {
  raw_ostream &os = emitter.ostream();
  Block &successor = *branchOp.getSuccessor();

  for (auto pair :
       llvm::zip(branchOp.getOperands(), successor.getArguments())) {
    Value &operand = std::get<0>(pair);
    BlockArgument &argument = std::get<1>(pair);
    os << emitter.getOrCreateName(argument) << " = "
       << emitter.getOrCreateName(operand) << ";\n";
  }

  os << "goto ";
  if (!(emitter.hasBlockLabel(successor)))
    return branchOp.emitOpError("unable to find label for successor block");
  os << emitter.getOrCreateName(successor);
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    cf::CondBranchOp condBranchOp) {
  raw_indented_ostream &os = emitter.ostream();
  Block &trueSuccessor = *condBranchOp.getTrueDest();
  Block &falseSuccessor = *condBranchOp.getFalseDest();

  os << "if (";
  if (failed(emitter.emitOperand(condBranchOp.getCondition())))
    return failure();
  os << ") {\n";

  os.indent();

  // If condition is true.
  for (auto pair : llvm::zip(condBranchOp.getTrueOperands(),
                             trueSuccessor.getArguments())) {
    Value &operand = std::get<0>(pair);
    BlockArgument &argument = std::get<1>(pair);
    os << emitter.getOrCreateName(argument) << " = "
       << emitter.getOrCreateName(operand) << ";\n";
  }

  os << "goto ";
  if (!(emitter.hasBlockLabel(trueSuccessor))) {
    return condBranchOp.emitOpError("unable to find label for successor block");
  }
  os << emitter.getOrCreateName(trueSuccessor) << ";\n";
  os.unindent() << "} else {\n";
  os.indent();
  // If condition is false.
  for (auto pair : llvm::zip(condBranchOp.getFalseOperands(),
                             falseSuccessor.getArguments())) {
    Value &operand = std::get<0>(pair);
    BlockArgument &argument = std::get<1>(pair);
    os << emitter.getOrCreateName(argument) << " = "
       << emitter.getOrCreateName(operand) << ";\n";
  }

  os << "goto ";
  if (!(emitter.hasBlockLabel(falseSuccessor))) {
    return condBranchOp.emitOpError()
           << "unable to find label for successor block";
  }
  os << emitter.getOrCreateName(falseSuccessor) << ";\n";
  os.unindent() << "}";
  return success();
}

static LogicalResult printCallOperation(CppEmitter &emitter, Operation *callOp,
                                        StringRef callee) {
  if (failed(emitter.emitAssignPrefix(*callOp)))
    return failure();

  raw_ostream &os = emitter.ostream();
  os << callee << "(";
  if (failed(emitter.emitOperands(*callOp)))
    return failure();
  os << ")";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, func::CallOp callOp) {
  Operation *operation = callOp.getOperation();
  StringRef callee = callOp.getCallee();

  return printCallOperation(emitter, operation, callee);
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::CallOp callOp) {
  Operation *operation = callOp.getOperation();
  StringRef callee = callOp.getCallee();

  return printCallOperation(emitter, operation, callee);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::CallOpaqueOp callOpaqueOp) {
  raw_ostream &os = emitter.ostream();
  Operation &op = *callOpaqueOp.getOperation();

  if (failed(emitter.emitAssignPrefix(op)))
    return failure();
  os << callOpaqueOp.getCallee();

  // Template arguments can't refer to SSA values and as such the template
  // arguments which are supplied in form of attributes can be emitted as is. We
  // don't need to handle integer attributes specially like we do for arguments
  // - see below.
  auto emitTemplateArgs = [&](Attribute attr) -> LogicalResult {
    return emitter.emitAttribute(op.getLoc(), attr);
  };

  if (callOpaqueOp.getTemplateArgs()) {
    os << "<";
    if (failed(interleaveCommaWithError(*callOpaqueOp.getTemplateArgs(), os,
                                        emitTemplateArgs)))
      return failure();
    os << ">";
  }

  auto emitArgs = [&](Attribute attr) -> LogicalResult {
    if (auto t = dyn_cast<IntegerAttr>(attr)) {
      // Index attributes are treated specially as operand index.
      if (t.getType().isIndex()) {
        int64_t idx = t.getInt();
        Value operand = op.getOperand(idx);
        return emitter.emitOperand(operand);
      }
    }
    if (failed(emitter.emitAttribute(op.getLoc(), attr)))
      return failure();

    return success();
  };

  os << "(";

  LogicalResult emittedArgs =
      callOpaqueOp.getArgs()
          ? interleaveCommaWithError(*callOpaqueOp.getArgs(), os, emitArgs)
          : emitter.emitOperands(op);
  if (failed(emittedArgs))
    return failure();
  os << ")";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::ApplyOp applyOp) {
  raw_ostream &os = emitter.ostream();
  Operation &op = *applyOp.getOperation();

  if (failed(emitter.emitAssignPrefix(op)))
    return failure();

  StringRef applicableOperator = applyOp.getApplicableOperator();
  Value operand = applyOp.getOperand();

  // Check if we're taking address of a const global.
  if (applicableOperator == "&" && getConstGlobal(operand, &op))
    return emitAddressOfWithConstCast(emitter, op, operand);

  os << applicableOperator;
  return emitter.emitOperand(operand);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::BitwiseAndOp bitwiseAndOp) {
  Operation *operation = bitwiseAndOp.getOperation();
  return printBinaryOperation(emitter, operation, "&");
}

static LogicalResult
printOperation(CppEmitter &emitter,
               emitc::BitwiseLeftShiftOp bitwiseLeftShiftOp) {
  Operation *operation = bitwiseLeftShiftOp.getOperation();
  return printBinaryOperation(emitter, operation, "<<");
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::BitwiseNotOp bitwiseNotOp) {
  Operation *operation = bitwiseNotOp.getOperation();
  return printUnaryOperation(emitter, operation, "~");
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::BitwiseOrOp bitwiseOrOp) {
  Operation *operation = bitwiseOrOp.getOperation();
  return printBinaryOperation(emitter, operation, "|");
}

static LogicalResult
printOperation(CppEmitter &emitter,
               emitc::BitwiseRightShiftOp bitwiseRightShiftOp) {
  Operation *operation = bitwiseRightShiftOp.getOperation();
  return printBinaryOperation(emitter, operation, ">>");
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::BitwiseXorOp bitwiseXorOp) {
  Operation *operation = bitwiseXorOp.getOperation();
  return printBinaryOperation(emitter, operation, "^");
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::UnaryPlusOp unaryPlusOp) {
  Operation *operation = unaryPlusOp.getOperation();
  return printUnaryOperation(emitter, operation, "+");
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::UnaryMinusOp unaryMinusOp) {
  Operation *operation = unaryMinusOp.getOperation();
  return printUnaryOperation(emitter, operation, "-");
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::CastOp castOp) {
  raw_ostream &os = emitter.ostream();
  Operation &op = *castOp.getOperation();

  if (failed(emitter.emitAssignPrefix(op)))
    return failure();
  os << "(";
  if (failed(emitter.emitType(op.getLoc(), op.getResult(0).getType())))
    return failure();
  os << ") ";
  return emitter.emitOperand(castOp.getOperand());
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::ExpressionOp expressionOp) {
  if (shouldBeInlined(expressionOp))
    return success();

  Operation &op = *expressionOp.getOperation();

  if (failed(emitter.emitAssignPrefix(op)))
    return failure();

  return emitter.emitExpression(expressionOp);
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::IncludeOp includeOp) {
  raw_ostream &os = emitter.ostream();

  os << "#include ";
  if (includeOp.getIsStandardInclude())
    os << "<" << includeOp.getInclude() << ">";
  else
    os << "\"" << includeOp.getInclude() << "\"";

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::LogicalAndOp logicalAndOp) {
  Operation *operation = logicalAndOp.getOperation();
  return printBinaryOperation(emitter, operation, "&&");
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::LogicalNotOp logicalNotOp) {
  Operation *operation = logicalNotOp.getOperation();
  return printUnaryOperation(emitter, operation, "!");
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::LogicalOrOp logicalOrOp) {
  Operation *operation = logicalOrOp.getOperation();
  return printBinaryOperation(emitter, operation, "||");
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::ForOp forOp) {
  raw_indented_ostream &os = emitter.ostream();

  // Utility function to determine whether a value is an expression that will be
  // inlined, and as such should be wrapped in parentheses in order to guarantee
  // its precedence and associativity.
  auto requiresParentheses = [&](Value value) {
    auto expressionOp = value.getDefiningOp<ExpressionOp>();
    if (!expressionOp)
      return false;
    return shouldBeInlined(expressionOp);
  };

  os << "for (";
  if (failed(
          emitter.emitType(forOp.getLoc(), forOp.getInductionVar().getType())))
    return failure();
  os << " ";
  os << emitter.getOrCreateInductionVarName(forOp.getInductionVar());
  os << " = ";
  if (failed(emitter.emitOperand(forOp.getLowerBound())))
    return failure();
  os << "; ";
  os << emitter.getOrCreateInductionVarName(forOp.getInductionVar());
  os << " < ";
  Value upperBound = forOp.getUpperBound();
  bool upperBoundRequiresParentheses = requiresParentheses(upperBound);
  if (upperBoundRequiresParentheses)
    os << "(";
  if (failed(emitter.emitOperand(upperBound)))
    return failure();
  if (upperBoundRequiresParentheses)
    os << ")";
  os << "; ";
  os << emitter.getOrCreateInductionVarName(forOp.getInductionVar());
  os << " += ";
  if (failed(emitter.emitOperand(forOp.getStep())))
    return failure();
  os << ") {\n";
  os.indent();

  CppEmitter::LoopScope lScope(emitter);

  Region &forRegion = forOp.getRegion();
  auto regionOps = forRegion.getOps();

  // We skip the trailing yield op.
  for (auto it = regionOps.begin(); std::next(it) != regionOps.end(); ++it) {
    if (failed(emitter.emitOperation(*it, /*trailingSemicolon=*/true)))
      return failure();
  }

  os.unindent() << "}";

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, emitc::IfOp ifOp) {
  raw_indented_ostream &os = emitter.ostream();

  // Helper function to emit all ops except the last one, expected to be
  // emitc::yield.
  auto emitAllExceptLast = [&emitter](Region &region) {
    Region::OpIterator it = region.op_begin(), end = region.op_end();
    for (; std::next(it) != end; ++it) {
      if (failed(emitter.emitOperation(*it, /*trailingSemicolon=*/true)))
        return failure();
    }
    assert(isa<emitc::YieldOp>(*it) &&
           "Expected last operation in the region to be emitc::yield");
    return success();
  };

  os << "if (";
  if (failed(emitter.emitOperand(ifOp.getCondition())))
    return failure();
  os << ") {\n";
  os.indent();
  if (failed(emitAllExceptLast(ifOp.getThenRegion())))
    return failure();
  os.unindent() << "}";

  Region &elseRegion = ifOp.getElseRegion();
  if (!elseRegion.empty()) {
    os << " else {\n";
    os.indent();
    if (failed(emitAllExceptLast(elseRegion)))
      return failure();
    os.unindent() << "}";
  }

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    func::ReturnOp returnOp) {
  raw_ostream &os = emitter.ostream();
  os << "return";
  switch (returnOp.getNumOperands()) {
  case 0:
    return success();
  case 1:
    os << " ";
    if (failed(emitter.emitOperand(returnOp.getOperand(0))))
      return failure();
    return success();
  default:
    os << " std::make_tuple(";
    if (failed(emitter.emitOperandsAndAttributes(*returnOp.getOperation())))
      return failure();
    os << ")";
    return success();
  }
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::ReturnOp returnOp) {
  raw_ostream &os = emitter.ostream();
  os << "return";
  if (returnOp.getNumOperands() == 0)
    return success();

  os << " ";
  if (failed(emitter.emitOperand(returnOp.getOperand())))
    return failure();
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, ModuleOp moduleOp) {
  for (Operation &op : moduleOp) {
    if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false)))
      return failure();
  }
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, ClassOp classOp) {
  raw_indented_ostream &os = emitter.ostream();
  os << "class " << classOp.getSymName();
  if (classOp.getFinalSpecifier())
    os << " final";
  os << " {\n public:\n";
  os.indent();

  for (Operation &op : classOp) {
    if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false)))
      return failure();
  }

  os.unindent();
  os << "};";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, FieldOp fieldOp) {
  raw_ostream &os = emitter.ostream();
  if (failed(emitter.emitVariableDeclaration(
          fieldOp->getLoc(), fieldOp.getType(), fieldOp.getSymName())))
    return failure();
  std::optional<Attribute> initialValue = fieldOp.getInitialValue();
  if (initialValue) {
    os << " = ";
    if (failed(emitter.emitAttribute(fieldOp->getLoc(), *initialValue)))
      return failure();
  }

  os << ";";
  return success();
}

static LogicalResult printOperation(CppEmitter &emitter, FileOp file) {
  if (!emitter.shouldEmitFile(file))
    return success();

  for (Operation &op : file) {
    if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false)))
      return failure();
  }
  return success();
}

static LogicalResult printFunctionArgs(CppEmitter &emitter,
                                       Operation *functionOp,
                                       ArrayRef<Type> arguments) {
  raw_indented_ostream &os = emitter.ostream();

  return (
      interleaveCommaWithError(arguments, os, [&](Type arg) -> LogicalResult {
        return emitter.emitType(functionOp->getLoc(), arg);
      }));
}

static LogicalResult printFunctionArgs(CppEmitter &emitter,
                                       Operation *functionOp,
                                       Region::BlockArgListType arguments) {
  raw_indented_ostream &os = emitter.ostream();

  return (interleaveCommaWithError(
      arguments, os, [&](BlockArgument arg) -> LogicalResult {
        return emitter.emitVariableDeclaration(
            functionOp->getLoc(), arg.getType(), emitter.getOrCreateName(arg));
      }));
}

static LogicalResult printFunctionBody(CppEmitter &emitter,
                                       Operation *functionOp,
                                       Region::BlockListType &blocks) {
  raw_indented_ostream &os = emitter.ostream();
  os.indent();

  if (emitter.shouldDeclareVariablesAtTop()) {
    // Declare all variables that hold op results including those from nested
    // regions.
    WalkResult result =
        functionOp->walk<WalkOrder::PreOrder>([&](Operation *op) -> WalkResult {
          if (isa<emitc::ExpressionOp>(op->getParentOp()) ||
              (isa<emitc::ExpressionOp>(op) &&
               shouldBeInlined(cast<emitc::ExpressionOp>(op))))
            return WalkResult::skip();
          for (OpResult result : op->getResults()) {
            if (failed(emitter.emitVariableDeclaration(
                    result, /*trailingSemicolon=*/true))) {
              return WalkResult(
                  op->emitError("unable to declare result variable for op"));
            }
          }
          return WalkResult::advance();
        });
    if (result.wasInterrupted())
      return failure();
  }

  // Create label names for basic blocks.
  for (Block &block : blocks) {
    emitter.getOrCreateName(block);
  }

  // Declare variables for basic block arguments.
  for (Block &block : llvm::drop_begin(blocks)) {
    for (BlockArgument &arg : block.getArguments()) {
      if (emitter.hasValueInScope(arg))
        return functionOp->emitOpError(" block argument #")
               << arg.getArgNumber() << " is out of scope";
      if (isa<ArrayType, LValueType>(arg.getType()))
        return functionOp->emitOpError("cannot emit block argument #")
               << arg.getArgNumber() << " with type " << arg.getType();
      if (failed(
              emitter.emitType(block.getParentOp()->getLoc(), arg.getType()))) {
        return failure();
      }
      os << " " << emitter.getOrCreateName(arg) << ";\n";
    }
  }

  for (Block &block : blocks) {
    // Only print a label if the block has predecessors.
    if (!block.hasNoPredecessors()) {
      if (failed(emitter.emitLabel(block)))
        return failure();
    }
    for (Operation &op : block.getOperations()) {
      if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/true)))
        return failure();
    }
  }

  os.unindent();

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    func::FuncOp functionOp) {
  // We need to declare variables at top if the function has multiple blocks.
  if (!emitter.shouldDeclareVariablesAtTop() &&
      functionOp.getBlocks().size() > 1) {
    return functionOp.emitOpError(
        "with multiple blocks needs variables declared at top");
  }

  if (llvm::any_of(functionOp.getArgumentTypes(), llvm::IsaPred<LValueType>)) {
    return functionOp.emitOpError()
           << "cannot emit lvalue type as argument type";
  }

  if (llvm::any_of(functionOp.getResultTypes(), llvm::IsaPred<ArrayType>)) {
    return functionOp.emitOpError() << "cannot emit array type as result type";
  }

  CppEmitter::FunctionScope scope(emitter);
  raw_indented_ostream &os = emitter.ostream();
  if (failed(emitter.emitTypes(functionOp.getLoc(),
                               functionOp.getFunctionType().getResults())))
    return failure();
  os << " " << functionOp.getName();

  os << "(";
  Operation *operation = functionOp.getOperation();
  if (failed(printFunctionArgs(emitter, operation, functionOp.getArguments())))
    return failure();
  os << ") {\n";
  if (failed(printFunctionBody(emitter, operation, functionOp.getBlocks())))
    return failure();
  os << "}";

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    emitc::FuncOp functionOp) {
  // We need to declare variables at top if the function has multiple blocks.
  if (!emitter.shouldDeclareVariablesAtTop() &&
      functionOp.getBlocks().size() > 1) {
    return functionOp.emitOpError(
        "with multiple blocks needs variables declared at top");
  }

  CppEmitter::FunctionScope scope(emitter);
  raw_indented_ostream &os = emitter.ostream();
  if (functionOp.getSpecifiers()) {
    for (Attribute specifier : functionOp.getSpecifiersAttr()) {
      os << cast<StringAttr>(specifier).str() << " ";
    }
  }

  if (failed(emitter.emitTypes(functionOp.getLoc(),
                               functionOp.getFunctionType().getResults())))
    return failure();
  os << " " << functionOp.getName();

  os << "(";
  Operation *operation = functionOp.getOperation();
  if (functionOp.isExternal()) {
    if (failed(printFunctionArgs(emitter, operation,
                                 functionOp.getArgumentTypes())))
      return failure();
    os << ");";
    return success();
  }
  if (failed(printFunctionArgs(emitter, operation, functionOp.getArguments())))
    return failure();
  os << ") {\n";
  if (failed(printFunctionBody(emitter, operation, functionOp.getBlocks())))
    return failure();
  os << "}";

  return success();
}

static LogicalResult printOperation(CppEmitter &emitter,
                                    DeclareFuncOp declareFuncOp) {
  raw_indented_ostream &os = emitter.ostream();

  CppEmitter::FunctionScope scope(emitter);
  auto functionOp = SymbolTable::lookupNearestSymbolFrom<emitc::FuncOp>(
      declareFuncOp, declareFuncOp.getSymNameAttr());

  if (!functionOp)
    return failure();

  if (functionOp.getSpecifiers()) {
    for (Attribute specifier : functionOp.getSpecifiersAttr()) {
      os << cast<StringAttr>(specifier).str() << " ";
    }
  }

  if (failed(emitter.emitTypes(functionOp.getLoc(),
                               functionOp.getFunctionType().getResults())))
    return failure();
  os << " " << functionOp.getName();

  os << "(";
  Operation *operation = functionOp.getOperation();
  if (failed(printFunctionArgs(emitter, operation, functionOp.getArguments())))
    return failure();
  os << ");";

  return success();
}

CppEmitter::CppEmitter(raw_ostream &os, bool declareVariablesAtTop,
                       StringRef fileId)
    : os(os), declareVariablesAtTop(declareVariablesAtTop),
      fileId(fileId.str()), defaultValueMapperScope(valueMapper),
      defaultBlockMapperScope(blockMapper) {
  labelInScopeCount.push(0);
}

/// Return the existing or a new name for a Value.
StringRef CppEmitter::getOrCreateName(Value val) {
  if (!valueMapper.count(val)) {
    valueMapper.insert(val, formatv("v{0}", ++valueCount));
  }
  return *valueMapper.begin(val);
}

/// Return the existing or a new name for a loop induction variable Value.
/// Loop induction variables follow natural naming: i, j, k, ..., t, uX.
StringRef CppEmitter::getOrCreateInductionVarName(Value val) {
  if (!valueMapper.count(val)) {

    int64_t identifier = 'i' + loopNestingLevel;

    if (identifier >= 'i' && identifier <= 't') {
      valueMapper.insert(val,
                         formatv("{0}{1}", (char)identifier, ++valueCount));
    } else {
      // If running out of letters, continue with uX.
      valueMapper.insert(val, formatv("u{0}", ++valueCount));
    }
  }
  return *valueMapper.begin(val);
}

/// Return the existing or a new label for a Block.
StringRef CppEmitter::getOrCreateName(Block &block) {
  if (!blockMapper.count(&block))
    blockMapper.insert(&block, formatv("label{0}", ++labelInScopeCount.top()));
  return *blockMapper.begin(&block);
}

bool CppEmitter::shouldMapToUnsigned(IntegerType::SignednessSemantics val) {
  switch (val) {
  case IntegerType::Signless:
    return false;
  case IntegerType::Signed:
    return false;
  case IntegerType::Unsigned:
    return true;
  }
  llvm_unreachable("Unexpected IntegerType::SignednessSemantics");
}

bool CppEmitter::hasValueInScope(Value val) { return valueMapper.count(val); }

bool CppEmitter::hasBlockLabel(Block &block) {
  return blockMapper.count(&block);
}

LogicalResult CppEmitter::emitAttribute(Location loc, Attribute attr) {
  auto printInt = [&](const APInt &val, bool isUnsigned) {
    if (val.getBitWidth() == 1) {
      if (val.getBoolValue())
        os << "true";
      else
        os << "false";
    } else {
      SmallString<128> strValue;
      val.toString(strValue, 10, !isUnsigned, false);
      os << strValue;
    }
  };

  auto printFloat = [&](const APFloat &val) {
    if (val.isFinite()) {
      SmallString<128> strValue;
      // Use default values of toString except don't truncate zeros.
      val.toString(strValue, 0, 0, false);
      os << strValue;
      switch (llvm::APFloatBase::SemanticsToEnum(val.getSemantics())) {
      case llvm::APFloatBase::S_IEEEhalf:
        os << "f16";
        break;
      case llvm::APFloatBase::S_BFloat:
        os << "bf16";
        break;
      case llvm::APFloatBase::S_IEEEsingle:
        os << "f";
        break;
      case llvm::APFloatBase::S_IEEEdouble:
        break;
      default:
        llvm_unreachable("unsupported floating point type");
      };
    } else if (val.isNaN()) {
      os << "NAN";
    } else if (val.isInfinity()) {
      if (val.isNegative())
        os << "-";
      os << "INFINITY";
    }
  };

  // Print floating point attributes.
  if (auto fAttr = dyn_cast<FloatAttr>(attr)) {
    if (!isa<Float16Type, BFloat16Type, Float32Type, Float64Type>(
            fAttr.getType())) {
      return emitError(
          loc, "expected floating point attribute to be f16, bf16, f32 or f64");
    }
    printFloat(fAttr.getValue());
    return success();
  }
  if (auto dense = dyn_cast<DenseFPElementsAttr>(attr)) {
    if (!isa<Float16Type, BFloat16Type, Float32Type, Float64Type>(
            dense.getElementType())) {
      return emitError(
          loc, "expected floating point attribute to be f16, bf16, f32 or f64");
    }
    os << '{';
    interleaveComma(dense, os, [&](const APFloat &val) { printFloat(val); });
    os << '}';
    return success();
  }

  // Print integer attributes.
  if (auto iAttr = dyn_cast<IntegerAttr>(attr)) {
    if (auto iType = dyn_cast<IntegerType>(iAttr.getType())) {
      printInt(iAttr.getValue(), shouldMapToUnsigned(iType.getSignedness()));
      return success();
    }
    if (auto iType = dyn_cast<IndexType>(iAttr.getType())) {
      printInt(iAttr.getValue(), false);
      return success();
    }
  }
  if (auto dense = dyn_cast<DenseIntElementsAttr>(attr)) {
    if (auto iType = dyn_cast<IntegerType>(
            cast<ShapedType>(dense.getType()).getElementType())) {
      os << '{';
      interleaveComma(dense, os, [&](const APInt &val) {
        printInt(val, shouldMapToUnsigned(iType.getSignedness()));
      });
      os << '}';
      return success();
    }
    if (auto iType = dyn_cast<IndexType>(
            cast<ShapedType>(dense.getType()).getElementType())) {
      os << '{';
      interleaveComma(dense, os,
                      [&](const APInt &val) { printInt(val, false); });
      os << '}';
      return success();
    }
  }

  // Print opaque attributes.
  if (auto oAttr = dyn_cast<emitc::OpaqueAttr>(attr)) {
    os << oAttr.getValue();
    return success();
  }

  // Print symbolic reference attributes.
  if (auto sAttr = dyn_cast<SymbolRefAttr>(attr)) {
    if (sAttr.getNestedReferences().size() > 1)
      return emitError(loc, "attribute has more than 1 nested reference");
    os << sAttr.getRootReference().getValue();
    return success();
  }

  // Print type attributes.
  if (auto type = dyn_cast<TypeAttr>(attr))
    return emitType(loc, type.getValue());

  return emitError(loc, "cannot emit attribute: ") << attr;
}

LogicalResult CppEmitter::emitExpression(Operation *op) {
  assert(emittedExpressionPrecedence.empty() &&
         "Expected precedence stack to be empty");
  Operation *rootOp = nullptr;

  if (auto expressionOp = dyn_cast<ExpressionOp>(op)) {
    rootOp = expressionOp.getRootOp();
  } else {
    assert(cast<CExpressionInterface>(op).alwaysInline() &&
           "Expected an always-inline operation");
    assert(!isa<ExpressionOp>(op->getParentOp()) &&
           "Expected operation to have no containing expression");
    rootOp = op;
  }
  FailureOr<int> precedence = getOperatorPrecedence(rootOp);
  if (failed(precedence))
    return failure();
  pushExpressionPrecedence(precedence.value());

  if (failed(emitOperation(*rootOp, /*trailingSemicolon=*/false)))
    return failure();

  popExpressionPrecedence();
  assert(emittedExpressionPrecedence.empty() &&
         "Expected precedence stack to be empty");

  return success();
}

LogicalResult CppEmitter::emitOperand(Value value, bool isInBrackets) {
  if (isPartOfCurrentExpression(value)) {
    Operation *def = value.getDefiningOp();
    assert(def && "Expected operand to be defined by an operation");
    if (auto expressionOp = dyn_cast<ExpressionOp>(def))
      def = expressionOp.getRootOp();
    FailureOr<int> precedence = getOperatorPrecedence(def);
    if (failed(precedence))
      return failure();

    // Unless already in brackets, sub-expressions with equal or lower
    // precedence need to be parenthesized as they might be evaluated in the
    // wrong order depending on the shape of the expression tree.
    bool encloseInParenthesis =
        !isInBrackets && precedence.value() <= getExpressionPrecedence();

    if (encloseInParenthesis)
      os << "(";
    pushExpressionPrecedence(precedence.value());

    if (failed(emitOperation(*def, /*trailingSemicolon=*/false)))
      return failure();

    if (encloseInParenthesis)
      os << ")";

    popExpressionPrecedence();
    return success();
  }

  if (Operation *def = value.getDefiningOp(); def && shouldBeInlined(def))
    return emitExpression(def);

  if (BlockArgument arg = dyn_cast<BlockArgument>(value)) {
    // If this operand is a block argument of an expression, emit instead the
    // matching expression parameter.
    Operation *argOp = arg.getParentBlock()->getParentOp();
    if (auto expressionOp = dyn_cast<ExpressionOp>(argOp))
      return emitOperand(expressionOp->getOperand(arg.getArgNumber()));
  }

  os << getOrCreateName(value);
  return success();
}

LogicalResult CppEmitter::emitOperands(Operation &op) {
  return interleaveCommaWithError(op.getOperands(), os, [&](Value operand) {
    // Emit operand under guarantee that if it's part of an expression then it
    // is being emitted within brackets.
    return emitOperand(operand, /*isInBrackets=*/true);
  });
}

LogicalResult
CppEmitter::emitOperandsAndAttributes(Operation &op,
                                      ArrayRef<StringRef> exclude) {
  if (failed(emitOperands(op)))
    return failure();
  // Insert comma in between operands and non-filtered attributes if needed.
  if (op.getNumOperands() > 0) {
    for (NamedAttribute attr : op.getAttrs()) {
      if (!llvm::is_contained(exclude, attr.getName().strref())) {
        os << ", ";
        break;
      }
    }
  }
  // Emit attributes.
  auto emitNamedAttribute = [&](NamedAttribute attr) -> LogicalResult {
    if (llvm::is_contained(exclude, attr.getName().strref()))
      return success();
    os << "/* " << attr.getName().getValue() << " */";
    if (failed(emitAttribute(op.getLoc(), attr.getValue())))
      return failure();
    return success();
  };
  return interleaveCommaWithError(op.getAttrs(), os, emitNamedAttribute);
}

LogicalResult CppEmitter::emitVariableAssignment(OpResult result) {
  if (!hasValueInScope(result)) {
    return result.getDefiningOp()->emitOpError(
        "result variable for the operation has not been declared");
  }
  os << getOrCreateName(result) << " = ";
  return success();
}

LogicalResult CppEmitter::emitVariableDeclaration(OpResult result,
                                                  bool trailingSemicolon) {
  if (auto cExpression =
          dyn_cast<CExpressionInterface>(result.getDefiningOp())) {
    if (cExpression.alwaysInline())
      return success();
  }
  if (hasValueInScope(result)) {
    return result.getDefiningOp()->emitError(
        "result variable for the operation already declared");
  }
  if (failed(emitVariableDeclaration(result.getOwner()->getLoc(),
                                     result.getType(),
                                     getOrCreateName(result))))
    return failure();
  if (trailingSemicolon)
    os << ";\n";
  return success();
}

LogicalResult CppEmitter::emitGlobalVariable(GlobalOp op) {
  if (op.getExternSpecifier())
    os << "extern ";
  else if (op.getStaticSpecifier())
    os << "static ";
  if (op.getConstSpecifier())
    os << "const ";

  if (failed(emitVariableDeclaration(op->getLoc(), op.getType(),
                                     op.getSymName()))) {
    return failure();
  }

  std::optional<Attribute> initialValue = op.getInitialValue();
  if (initialValue) {
    os << " = ";
    if (failed(emitAttribute(op->getLoc(), *initialValue)))
      return failure();
  }

  os << ";";
  return success();
}

LogicalResult CppEmitter::emitAssignPrefix(Operation &op) {
  // If op is being emitted as part of an expression, bail out.
  if (isEmittingExpression())
    return success();

  switch (op.getNumResults()) {
  case 0:
    break;
  case 1: {
    OpResult result = op.getResult(0);
    if (shouldDeclareVariablesAtTop()) {
      if (failed(emitVariableAssignment(result)))
        return failure();
    } else {
      if (failed(emitVariableDeclaration(result, /*trailingSemicolon=*/false)))
        return failure();
      os << " = ";
    }
    break;
  }
  default:
    if (!shouldDeclareVariablesAtTop()) {
      for (OpResult result : op.getResults()) {
        if (failed(emitVariableDeclaration(result, /*trailingSemicolon=*/true)))
          return failure();
      }
    }
    os << "std::tie(";
    interleaveComma(op.getResults(), os,
                    [&](Value result) { os << getOrCreateName(result); });
    os << ") = ";
  }
  return success();
}

LogicalResult CppEmitter::emitLabel(Block &block) {
  if (!hasBlockLabel(block))
    return block.getParentOp()->emitError("label for block not found");
  // FIXME: Add feature in `raw_indented_ostream` to ignore indent for block
  // label instead of using `getOStream`.
  os.getOStream() << getOrCreateName(block) << ":\n";
  return success();
}

LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
  LogicalResult status =
      llvm::TypeSwitch<Operation *, LogicalResult>(&op)
          // Builtin ops.
          .Case([&](ModuleOp op) { return printOperation(*this, op); })
          // CF ops.
          .Case<cf::BranchOp, cf::CondBranchOp>(
              [&](auto op) { return printOperation(*this, op); })
          // EmitC ops.
          .Case<emitc::AddressOfOp, emitc::AddOp, emitc::ApplyOp,
                emitc::AssignOp, emitc::BitwiseAndOp, emitc::BitwiseLeftShiftOp,
                emitc::BitwiseNotOp, emitc::BitwiseOrOp,
                emitc::BitwiseRightShiftOp, emitc::BitwiseXorOp, emitc::CallOp,
                emitc::CallOpaqueOp, emitc::CastOp, emitc::ClassOp,
                emitc::CmpOp, emitc::ConditionalOp, emitc::ConstantOp,
                emitc::DeclareFuncOp, emitc::DereferenceOp, emitc::DivOp,
                emitc::DoOp, emitc::ExpressionOp, emitc::FieldOp, emitc::FileOp,
                emitc::ForOp, emitc::FuncOp, emitc::GetFieldOp,
                emitc::GetGlobalOp, emitc::GlobalOp, emitc::IfOp,
                emitc::IncludeOp, emitc::LiteralOp, emitc::LoadOp,
                emitc::LogicalAndOp, emitc::LogicalNotOp, emitc::LogicalOrOp,
                emitc::MemberOfPtrOp, emitc::MemberOp, emitc::MulOp,
                emitc::RemOp, emitc::ReturnOp, emitc::SubscriptOp, emitc::SubOp,
                emitc::SwitchOp, emitc::UnaryMinusOp, emitc::UnaryPlusOp,
                emitc::VariableOp, emitc::VerbatimOp>(

              [&](auto op) { return printOperation(*this, op); })
          // Func ops.
          .Case<func::CallOp, func::FuncOp, func::ReturnOp>(
              [&](auto op) { return printOperation(*this, op); })
          .Default([&](Operation *) {
            return op.emitOpError("unable to find printer for op");
          });

  if (failed(status))
    return failure();

  if (auto cExpression = dyn_cast<CExpressionInterface>(op)) {
    if (cExpression.alwaysInline())
      return success();
  }

  if (isEmittingExpression() ||
      (isa<emitc::ExpressionOp>(op) &&
       shouldBeInlined(cast<emitc::ExpressionOp>(op))))
    return success();

  // Never emit a semicolon for some operations, especially if endening with
  // `}`.
  trailingSemicolon &=
      !isa<cf::CondBranchOp, emitc::DeclareFuncOp, emitc::DoOp, emitc::FileOp,
           emitc::ForOp, emitc::IfOp, emitc::IncludeOp, emitc::SwitchOp,
           emitc::VerbatimOp>(op);

  os << (trailingSemicolon ? ";\n" : "\n");

  return success();
}

LogicalResult CppEmitter::emitVariableDeclaration(Location loc, Type type,
                                                  StringRef name) {
  if (auto arrType = dyn_cast<emitc::ArrayType>(type)) {
    if (failed(emitType(loc, arrType.getElementType())))
      return failure();
    os << " " << name;
    for (auto dim : arrType.getShape()) {
      os << "[" << dim << "]";
    }
    return success();
  }
  if (failed(emitType(loc, type)))
    return failure();
  os << " " << name;
  return success();
}

LogicalResult CppEmitter::emitType(Location loc, Type type) {
  if (auto iType = dyn_cast<IntegerType>(type)) {
    switch (iType.getWidth()) {
    case 1:
      return (os << "bool"), success();
    case 8:
    case 16:
    case 32:
    case 64:
      if (shouldMapToUnsigned(iType.getSignedness()))
        return (os << "uint" << iType.getWidth() << "_t"), success();
      else
        return (os << "int" << iType.getWidth() << "_t"), success();
    default:
      return emitError(loc, "cannot emit integer type ") << type;
    }
  }
  if (auto fType = dyn_cast<FloatType>(type)) {
    switch (fType.getWidth()) {
    case 16: {
      if (llvm::isa<Float16Type>(type))
        return (os << "_Float16"), success();
      if (llvm::isa<BFloat16Type>(type))
        return (os << "__bf16"), success();
      else
        return emitError(loc, "cannot emit float type ") << type;
    }
    case 32:
      return (os << "float"), success();
    case 64:
      return (os << "double"), success();
    default:
      return emitError(loc, "cannot emit float type ") << type;
    }
  }
  if (auto iType = dyn_cast<IndexType>(type))
    return (os << "size_t"), success();
  if (auto sType = dyn_cast<emitc::SizeTType>(type))
    return (os << "size_t"), success();
  if (auto sType = dyn_cast<emitc::SignedSizeTType>(type))
    return (os << "ssize_t"), success();
  if (auto pType = dyn_cast<emitc::PtrDiffTType>(type))
    return (os << "ptrdiff_t"), success();
  if (auto tType = dyn_cast<TensorType>(type)) {
    if (!tType.hasRank())
      return emitError(loc, "cannot emit unranked tensor type");
    if (!tType.hasStaticShape())
      return emitError(loc, "cannot emit tensor type with non static shape");
    os << "Tensor<";
    if (isa<ArrayType>(tType.getElementType()))
      return emitError(loc, "cannot emit tensor of array type ") << type;
    if (failed(emitType(loc, tType.getElementType())))
      return failure();
    auto shape = tType.getShape();
    for (auto dimSize : shape) {
      os << ", ";
      os << dimSize;
    }
    os << ">";
    return success();
  }
  if (auto tType = dyn_cast<TupleType>(type))
    return emitTupleType(loc, tType.getTypes());
  if (auto oType = dyn_cast<emitc::OpaqueType>(type)) {
    os << oType.getValue();
    return success();
  }
  if (auto aType = dyn_cast<emitc::ArrayType>(type)) {
    if (failed(emitType(loc, aType.getElementType())))
      return failure();
    for (auto dim : aType.getShape())
      os << "[" << dim << "]";
    return success();
  }
  if (auto lType = dyn_cast<emitc::LValueType>(type))
    return emitType(loc, lType.getValueType());
  if (auto pType = dyn_cast<emitc::PointerType>(type)) {
    if (isa<ArrayType>(pType.getPointee()))
      return emitError(loc, "cannot emit pointer to array type ") << type;
    if (failed(emitType(loc, pType.getPointee())))
      return failure();
    os << "*";
    return success();
  }
  return emitError(loc, "cannot emit type ") << type;
}

LogicalResult CppEmitter::emitTypes(Location loc, ArrayRef<Type> types) {
  switch (types.size()) {
  case 0:
    os << "void";
    return success();
  case 1:
    return emitType(loc, types.front());
  default:
    return emitTupleType(loc, types);
  }
}

LogicalResult CppEmitter::emitTupleType(Location loc, ArrayRef<Type> types) {
  if (llvm::any_of(types, llvm::IsaPred<ArrayType>)) {
    return emitError(loc, "cannot emit tuple of array type");
  }
  os << "std::tuple<";
  if (failed(interleaveCommaWithError(
          types, os, [&](Type type) { return emitType(loc, type); })))
    return failure();
  os << ">";
  return success();
}

void CppEmitter::resetValueCounter() { valueCount = 0; }

void CppEmitter::increaseLoopNestingLevel() { loopNestingLevel++; }

void CppEmitter::decreaseLoopNestingLevel() { loopNestingLevel--; }

LogicalResult emitc::translateToCpp(Operation *op, raw_ostream &os,
                                    bool declareVariablesAtTop,
                                    StringRef fileId) {
  CppEmitter emitter(os, declareVariablesAtTop, fileId);
  return emitter.emitOperation(*op, /*trailingSemicolon=*/false);
}
