Repository: llvm/llvm-project
File: flang/lib/Lower/OpenMP/ClauseProcessor.cpp (C++)

Code before:

  auto callbackFn = [&](const auto &clause, const parser::CharBlock &source) {
    mlir::Location clauseLocation = converter.genLocation(source);
    const auto &[expectation, mapper, iterator, objects] = clause.t;

    mlir::omp::ClauseMapFlags mapTypeBits =
        std::is_same_v<llvm::remove_cvref_t<decltype(clause)>, omp::clause::To>
            ? mlir::omp::ClauseMapFlags::to
            : mlir::omp::ClauseMapFlags::from;
    if (expectation && *expectation == omp::clause::To::Expectation::Present)
      mapTypeBits |= mlir::omp::ClauseMapFlags::present;

    // Support motion modifiers: mapper, iterator.
    std::string mapperIdName = "__implicit_mapper";
    if (mapper) {
      // Only one mapper is allowed by the parser here.
      assert(mapper->size() == 1 && "more than one mapper");
      const semantics::Symbol *mapperSym = mapper->front().v.id().symbol;
      mapperIdName = mapperSym->name().ToString();
      if (mapperIdName != "default") {
        // Mangle with the ultimate owner so that use-associated mapper
        // identifiers resolve to the same symbol as their defining scope.
        const semantics::Symbol &ultimate = mapperSym->GetUltimate();
        mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
      }
    }
    if (iterator) {
      TODO(clauseLocation, "Iterator modifier is not supported yet");
    }

    processMapObjects(stmtCtx, clauseLocation, objects, mapTypeBits,
                      parentMemberIndices, result.mapVars, mapSymbols,
                      mapperIdName);
  };

  bool clauseFound = findRepeatableClause<omp::clause::To>(callbackFn);
  clauseFound =
      findRepeatableClause<omp::clause::From>(callbackFn) || clauseFound;

  insertChildMapInfoIntoParent(converter, semaCtx, stmtCtx, parentMemberIndices,
                               result.mapVars, mapSymbols);

  return clauseFound;
}

bool ClauseProcessor::processNontemporal(
    mlir::omp::NontemporalClauseOps &result) const {
  return findRepeatableClause<omp::clause::Nontemporal>(
      [&](const omp::clause::Nontemporal &clause, const parser::CharBlock &) {
        for (const Object &object : clause.v) {
          semantics::Symbol *sym = object.sym();

Review comment (refactor):
This code is common to ClauseProcessor::processMap and should be put in a static function instead of duplicated.

Code after:
  };

  bool clauseFound = findRepeatableClause<omp::clause::Map>(process);
  insertChildMapInfoIntoParent(converter, semaCtx, stmtCtx, parentMemberIndices,
                               result.mapVars, *ptrMapSyms);

  return clauseFound;
}

bool ClauseProcessor::processMotionClauses(lower::StatementContext &stmtCtx,
                                           mlir::omp::MapClauseOps &result) {
  std::map<Object, OmpMapParentAndMemberData> parentMemberIndices;
  llvm::SmallVector<const semantics::Symbol *> mapSymbols;

  auto callbackFn = [&](const auto &clause, const parser::CharBlock &source) {
    mlir::Location clauseLocation = converter.genLocation(source);
    const auto &[expectation, mapper, iterator, objects] = clause.t;

    mlir::omp::ClauseMapFlags mapTypeBits =
        std::is_same_v<llvm::remove_cvref_t<decltype(clause)>, omp::clause::To>
            ? mlir::omp::ClauseMapFlags::to
            : mlir::omp::ClauseMapFlags::from;
    if (expectation && *expectation == omp::clause::To::Expectation::Present)
      mapTypeBits |= mlir::omp::ClauseMapFlags::present;

    // Support motion modifiers: mapper, iterator.
    std::string mapperIdName = getMapperIdentifier(converter, mapper);
    if (iterator) {
      TODO(clauseLocation, "Iterator modifier is not supported yet");
    }

    processMapObjects(stmtCtx, clauseLocation, objects, mapTypeBits,
                      parentMemberIndices, result.mapVars, mapSymbols,
                      mapperIdName);
  };

  bool clauseFound = findRepeatableClause<omp::clause::To>(callbackFn);
  clauseFound =
      findRepeatableClause<omp::clause::From>(callbackFn) || clauseFound;

  insertChildMapInfoIntoParent(converter, semaCtx, stmtCtx, parentMemberIndices,
                               result.mapVars, mapSymbols);

  return clauseFound;
}

bool ClauseProcessor::processNontemporal(
    mlir::omp::NontemporalClauseOps &result) const {
  return findRepeatableClause<omp::clause::Nontemporal>(
      [&](const omp::clause::Nontemporal &clause, const parser::CharBlock &) {
        for (const Object &object : clause.v) {