void MatcherGen::EmitMatchCode(const TreePatternNode *N,
                               TreePatternNode *NodeNoTypes,
                               unsigned ForceMode) {
  // If N and NodeNoTypes don't agree on a type, then this is a case where we
  // need to do a type check.  Emit the check, apply the type to NodeNoTypes and
  // reinfer any correlated types.
  SmallVector<unsigned, 2> ResultsToTypeCheck;

  for (unsigned i = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) {
    if (NodeNoTypes->getExtType(i) == N->getExtType(i)) continue;
    NodeNoTypes->setType(i, N->getExtType(i));
    InferPossibleTypes(ForceMode);
    ResultsToTypeCheck.push_back(i);
  }

  // If this node has a name associated with it, capture it in VariableMap. If
  // we already saw this in the pattern, emit code to verify dagness.
  SmallVector<std::string, 4> Names;
  if (!N->getName().empty())
    Names.push_back(N->getName());

  for (const ScopedName &Name : N->getNamesAsPredicateArg()) {
    Names.push_back(("pred:" + Twine(Name.getScope()) + ":" + Name.getIdentifier()).str());
  }

  if (!Names.empty()) {
    if (!recordUniqueNode(Names))
      return;
  }

  if (N->isLeaf())
    EmitLeafMatchCode(N);
  else
    EmitOperatorMatchCode(N, NodeNoTypes, ForceMode);

  // If there are node predicates for this node, generate their checks.
  for (unsigned i = 0, e = N->getPredicateCalls().size(); i != e; ++i) {
    const TreePredicateCall &Pred = N->getPredicateCalls()[i];
    SmallVector<unsigned, 4> Operands;
    if (Pred.Fn.usesOperands()) {
      TreePattern *TP = Pred.Fn.getOrigPatFragRecord();
      for (unsigned i = 0; i < TP->getNumArgs(); ++i) {
        std::string Name =
            ("pred:" + Twine(Pred.Scope) + ":" + TP->getArgName(i)).str();
        Operands.push_back(getNamedArgumentSlot(Name));
      }
    }
    AddMatcher(new CheckPredicateMatcher(Pred.Fn, Operands));
  }

  for (unsigned i = 0, e = ResultsToTypeCheck.size(); i != e; ++i)
    AddMatcher(new CheckTypeMatcher(N->getSimpleType(ResultsToTypeCheck[i]),
                                    ResultsToTypeCheck[i]));
}