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

Code before:
        /*varPtrPtr=*/mlir::Value{}, asFortran.str(), bounds,
        /*members=*/{}, /*membersIndex=*/mlir::ArrayAttr{}, mapTypeBits,
        mlir::omp::VariableCaptureKind::ByRef, baseOp.getType(),
        /*partialMap=*/false, mapperId);

    if (parentObj.has_value()) {
      parentMemberIndices[parentObj.value()].addChildIndexAndMapToParent(
          object, mapOp, semaCtx);
    } else {
      mapVars.push_back(mapOp);
      mapSyms.push_back(object.sym());
    }
  }
}

/// Extract and mangle the mapper identifier name from a mapper clause.
/// Returns "__implicit_mapper" if no mapper is specified, or "default" if
/// the default mapper is specified, otherwise returns the mangled mapper name.
/// This handles both the Map clause (which uses a vector of mappers) and
/// To/From clauses (which use a DefinedOperator).
template <typename MapperType>
static std::string
getMapperIdentifier(lower::AbstractConverter &converter,
                    const std::optional<MapperType> &mapper) {
  std::string mapperIdName = "__implicit_mapper";
  if (mapper) {
    const semantics::Symbol *mapperSym = nullptr;

    // Handle different mapper types
    if constexpr (std::is_same_v<MapperType, omp::clause::DefinedOperator>) {
      // For To/From clauses: mapper is a DefinedOperator
      assert(mapper->size() == 1 && "more than one mapper");
      mapperSym = mapper->front().v.id().symbol;
    } else {
      // For Map clause: mappers is a vector
      assert(mapper->size() == 1 && "more than one mapper");
      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());
    }
  }
  return mapperIdName;
}

bool ClauseProcessor::processMap(

Review comment (refactor):
Nit: Prefer [early return](https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code) to reduce nesting.

```suggestion
  if (!mapper)
    return "__implicit_mapper";
```

Code after:
        /*partialMap=*/false, mapperId);

    if (parentObj.has_value()) {
      parentMemberIndices[parentObj.value()].addChildIndexAndMapToParent(
          object, mapOp, semaCtx);
    } else {
      mapVars.push_back(mapOp);
      mapSyms.push_back(object.sym());
    }
  }
}

/// Extract and mangle the mapper identifier name from a mapper clause.
/// Returns "__implicit_mapper" if no mapper is specified, or "default" if
/// the default mapper is specified, otherwise returns the mangled mapper name.
/// This handles both the Map clause (which uses a vector of mappers) and
/// To/From clauses (which use a DefinedOperator).
template <typename MapperType>
static std::string
getMapperIdentifier(lower::AbstractConverter &converter,
                    const std::optional<MapperType> &mapper) {
  if (!mapper)
    return "__implicit_mapper";

  // Handle mapper types (both have the same structure)
  assert(mapper->size() == 1 && "more than one mapper");
  const semantics::Symbol *mapperSym = mapper->front().v.id().symbol;

  std::string 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());
  }
  return mapperIdName;
}

bool ClauseProcessor::processMap(
    mlir::Location currentLocation, lower::StatementContext &stmtCtx,
    mlir::omp::MapClauseOps &result, llvm::omp::Directive directive,
    llvm::SmallVectorImpl<const semantics::Symbol *> *mapSyms) const {
  // We always require tracking of symbols, even if the caller does not,
  // so we create an optionally used local set of symbols when the mapSyms
  // argument is not present.
  llvm::SmallVector<const semantics::Symbol *> localMapSyms;
  llvm::SmallVectorImpl<const semantics::Symbol *> *ptrMapSyms =
      mapSyms ? mapSyms : &localMapSyms;
  std::map<Object, OmpMapParentAndMemberData> parentMemberIndices;

  auto process = [&](const omp::clause::Map &clause,