//===- DebugTranslation.cpp - MLIR to LLVM Debug conversion ---------------===//
//
// 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 "DebugTranslation.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"

using namespace mlir;
using namespace mlir::LLVM;
using namespace mlir::LLVM::detail;

/// A utility walker that interrupts if the operation has valid debug
/// information.
static WalkResult interruptIfValidLocation(Operation *op) {
  return isa<UnknownLoc>(op->getLoc()) ? WalkResult::advance()
                                       : WalkResult::interrupt();
}

DebugTranslation::DebugTranslation(Operation *module, llvm::Module &llvmModule)
    : debugEmissionIsEnabled(false), llvmModule(llvmModule),
      llvmCtx(llvmModule.getContext()) {
  // If the module has no location information, there is nothing to do.
  if (!module->walk(interruptIfValidLocation).wasInterrupted())
    return;
  debugEmissionIsEnabled = true;

  // TODO: The version information should be encoded on the LLVM module itself,
  // not implicitly set here.

  // Mark this module as having debug information.
  StringRef debugVersionKey = "Debug Info Version";
  if (!llvmModule.getModuleFlag(debugVersionKey))
    llvmModule.addModuleFlag(llvm::Module::Warning, debugVersionKey,
                             llvm::DEBUG_METADATA_VERSION);

  if (auto targetTripleAttr = module->getDiscardableAttr(
          LLVM::LLVMDialect::getTargetTripleAttrName())) {
    auto targetTriple =
        llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue());
    if (targetTriple.isKnownWindowsMSVCEnvironment()) {
      // Dwarf debugging files will be generated by default, unless "CodeView"
      // is set explicitly. Windows/MSVC should use CodeView instead.
      llvmModule.addModuleFlag(llvm::Module::Warning, "CodeView", 1);
    }
  }
}

/// Finalize the translation of debug information.
void DebugTranslation::finalize() {}

/// Translate the debug information for the given function.
void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
  if (!debugEmissionIsEnabled)
    return;

  // Look for a sub program attached to the function.
  auto spLoc =
      func.getLoc()->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>();
  if (!spLoc)
    return;
  llvmFunc.setSubprogram(translate(spLoc.getMetadata()));
}

//===----------------------------------------------------------------------===//
// Attributes
//===----------------------------------------------------------------------===//

llvm::DIType *DebugTranslation::translateImpl(DINullTypeAttr attr) {
  // A DINullTypeAttr at the beginning of the subroutine types list models
  // a void result type. If it is at the end, it models a variadic function.
  // Translate the explicit DINullTypeAttr to a nullptr since LLVM IR metadata
  // does not have an explicit void result type nor a variadic type
  // representation.
  return nullptr;
}

llvm::DIExpression *
DebugTranslation::getExpressionAttrOrNull(DIExpressionAttr attr) {
  if (!attr)
    return nullptr;
  return translateExpression(attr);
}

llvm::MDString *DebugTranslation::getMDStringOrNull(StringAttr stringAttr) {
  if (!stringAttr || stringAttr.empty())
    return nullptr;
  return llvm::MDString::get(llvmCtx, stringAttr);
}

llvm::MDTuple *
DebugTranslation::getMDTupleOrNull(ArrayRef<DINodeAttr> elements) {
  if (elements.empty())
    return nullptr;
  SmallVector<llvm::Metadata *> llvmElements = llvm::to_vector(
      llvm::map_range(elements, [&](DINodeAttr attr) -> llvm::Metadata * {
        if (DIAnnotationAttr annAttr = dyn_cast<DIAnnotationAttr>(attr)) {
          llvm::Metadata *ops[2] = {
              llvm::MDString::get(llvmCtx, annAttr.getName()),
              llvm::MDString::get(llvmCtx, annAttr.getValue())};
          return llvm::MDNode::get(llvmCtx, ops);
        }
        return translate(attr);
      }));
  return llvm::MDNode::get(llvmCtx, llvmElements);
}

llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
  return llvm::DIBasicType::get(
      llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()),
      attr.getSizeInBits(),
      /*AlignInBits=*/0, attr.getEncoding(), llvm::DINode::FlagZero);
}

llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
  llvm::DIBuilder builder(llvmModule);
  return builder.createCompileUnit(
      attr.getSourceLanguage(), translate(attr.getFile()),
      attr.getProducer() ? attr.getProducer().getValue() : "",
      attr.getIsOptimized(),
      /*Flags=*/"", /*RV=*/0, /*SplitName=*/{},
      static_cast<llvm::DICompileUnit::DebugEmissionKind>(
          attr.getEmissionKind()),
      0, true, false,
      static_cast<llvm::DICompileUnit::DebugNameTableKind>(
          attr.getNameTableKind()));
}

/// Returns a new `DINodeT` that is either distinct or not, depending on
/// `isDistinct`.
template <class DINodeT, class... Ts>
static DINodeT *getDistinctOrUnique(bool isDistinct, Ts &&...args) {
  if (isDistinct)
    return DINodeT::getDistinct(std::forward<Ts>(args)...);
  return DINodeT::get(std::forward<Ts>(args)...);
}

llvm::TempDICompositeType
DebugTranslation::translateTemporaryImpl(DICompositeTypeAttr attr) {
  return llvm::DICompositeType::getTemporary(
      llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()), nullptr,
      attr.getLine(), nullptr, nullptr, attr.getSizeInBits(),
      attr.getAlignInBits(),
      /*OffsetInBits=*/0,
      /*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()),
      /*Elements=*/nullptr, /*RuntimeLang=*/0,
      /*VTableHolder=*/nullptr);
}

llvm::TempDISubprogram
DebugTranslation::translateTemporaryImpl(DISubprogramAttr attr) {
  return llvm::DISubprogram::getTemporary(
      llvmCtx, /*Scope=*/nullptr, /*Name=*/{}, /*LinkageName=*/{},
      /*File=*/nullptr, attr.getLine(), /*Type=*/nullptr,
      /*ScopeLine=*/0, /*ContainingType=*/nullptr, /*VirtualIndex=*/0,
      /*ThisAdjustment=*/0, llvm::DINode::FlagZero,
      static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
      /*Unit=*/nullptr);
}

llvm::DICompositeType *
DebugTranslation::translateImpl(DICompositeTypeAttr attr) {
  // TODO: Use distinct attributes to model this, once they have landed.
  // Depending on the tag, composite types must be distinct.
  bool isDistinct = false;
  switch (attr.getTag()) {
  case llvm::dwarf::DW_TAG_class_type:
  case llvm::dwarf::DW_TAG_enumeration_type:
  case llvm::dwarf::DW_TAG_structure_type:
  case llvm::dwarf::DW_TAG_union_type:
    isDistinct = true;
  }

  return getDistinctOrUnique<llvm::DICompositeType>(
      isDistinct, llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()),
      translate(attr.getFile()), attr.getLine(), translate(attr.getScope()),
      translate(attr.getBaseType()), attr.getSizeInBits(),
      attr.getAlignInBits(),
      /*OffsetInBits=*/0,
      /*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()),
      getMDTupleOrNull(attr.getElements()),
      /*RuntimeLang=*/0, /*VTableHolder=*/nullptr,
      /*TemplateParams=*/nullptr, /*Identifier=*/nullptr,
      /*Discriminator=*/nullptr,
      getExpressionAttrOrNull(attr.getDataLocation()),
      getExpressionAttrOrNull(attr.getAssociated()),
      getExpressionAttrOrNull(attr.getAllocated()),
      getExpressionAttrOrNull(attr.getRank()));
}

llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) {
  return llvm::DIDerivedType::get(
      llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()),
      /*File=*/nullptr, /*Line=*/0,
      /*Scope=*/nullptr, translate(attr.getBaseType()), attr.getSizeInBits(),
      attr.getAlignInBits(), attr.getOffsetInBits(),
      attr.getDwarfAddressSpace(), /*PtrAuthData=*/std::nullopt,
      /*Flags=*/llvm::DINode::FlagZero, translate(attr.getExtraData()));
}

llvm::DIStringType *DebugTranslation::translateImpl(DIStringTypeAttr attr) {
  return llvm::DIStringType::get(
      llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()),
      translate(attr.getStringLength()),
      getExpressionAttrOrNull(attr.getStringLengthExp()),
      getExpressionAttrOrNull(attr.getStringLocationExp()),
      attr.getSizeInBits(), attr.getAlignInBits(), attr.getEncoding());
}

llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) {
  return llvm::DIFile::get(llvmCtx, getMDStringOrNull(attr.getName()),
                           getMDStringOrNull(attr.getDirectory()));
}

llvm::DILabel *DebugTranslation::translateImpl(DILabelAttr attr) {
  return llvm::DILabel::get(llvmCtx, translate(attr.getScope()),
                            getMDStringOrNull(attr.getName()),
                            translate(attr.getFile()), attr.getLine());
}

llvm::DILexicalBlock *DebugTranslation::translateImpl(DILexicalBlockAttr attr) {
  return llvm::DILexicalBlock::getDistinct(llvmCtx, translate(attr.getScope()),
                                           translate(attr.getFile()),
                                           attr.getLine(), attr.getColumn());
}

llvm::DILexicalBlockFile *
DebugTranslation::translateImpl(DILexicalBlockFileAttr attr) {
  return llvm::DILexicalBlockFile::getDistinct(
      llvmCtx, translate(attr.getScope()), translate(attr.getFile()),
      attr.getDiscriminator());
}

llvm::DILocalScope *DebugTranslation::translateImpl(DILocalScopeAttr attr) {
  return cast<llvm::DILocalScope>(translate(DINodeAttr(attr)));
}

llvm::DIVariable *DebugTranslation::translateImpl(DIVariableAttr attr) {
  return cast<llvm::DIVariable>(translate(DINodeAttr(attr)));
}

llvm::DILocalVariable *
DebugTranslation::translateImpl(DILocalVariableAttr attr) {
  return llvm::DILocalVariable::get(
      llvmCtx, translate(attr.getScope()), getMDStringOrNull(attr.getName()),
      translate(attr.getFile()), attr.getLine(), translate(attr.getType()),
      attr.getArg(), static_cast<llvm::DINode::DIFlags>(attr.getFlags()),
      attr.getAlignInBits(),
      /*Annotations=*/nullptr);
}

llvm::DIGlobalVariable *
DebugTranslation::translateImpl(DIGlobalVariableAttr attr) {
  return llvm::DIGlobalVariable::getDistinct(
      llvmCtx, translate(attr.getScope()), getMDStringOrNull(attr.getName()),
      getMDStringOrNull(attr.getLinkageName()), translate(attr.getFile()),
      attr.getLine(), translate(attr.getType()), attr.getIsLocalToUnit(),
      attr.getIsDefined(), nullptr, nullptr, attr.getAlignInBits(), nullptr);
}

llvm::DINode *
DebugTranslation::translateRecursive(DIRecursiveTypeAttrInterface attr) {
  DistinctAttr recursiveId = attr.getRecId();
  if (auto *iter = recursiveNodeMap.find(recursiveId);
      iter != recursiveNodeMap.end()) {
    return iter->second;
  }
  assert(!attr.getIsRecSelf() && "unbound DI recursive self reference");

  auto setRecursivePlaceholder = [&](llvm::DINode *placeholder) {
    recursiveNodeMap.try_emplace(recursiveId, placeholder);
  };

  llvm::DINode *result =
      TypeSwitch<DIRecursiveTypeAttrInterface, llvm::DINode *>(attr)
          .Case<DICompositeTypeAttr>([&](auto attr) {
            auto temporary = translateTemporaryImpl(attr);
            setRecursivePlaceholder(temporary.get());
            // Must call `translateImpl` directly instead of `translate` to
            // avoid handling the recursive interface again.
            auto *concrete = translateImpl(attr);
            temporary->replaceAllUsesWith(concrete);
            return concrete;
          })
          .Case<DISubprogramAttr>([&](auto attr) {
            auto temporary = translateTemporaryImpl(attr);
            setRecursivePlaceholder(temporary.get());
            // Must call `translateImpl` directly instead of `translate` to
            // avoid handling the recursive interface again.
            auto *concrete = translateImpl(attr);
            temporary->replaceAllUsesWith(concrete);
            return concrete;
          });

  assert(recursiveNodeMap.back().first == recursiveId &&
         "internal inconsistency: unexpected recursive translation stack");
  recursiveNodeMap.pop_back();

  return result;
}

llvm::DIScope *DebugTranslation::translateImpl(DIScopeAttr attr) {
  return cast<llvm::DIScope>(translate(DINodeAttr(attr)));
}

llvm::DISubprogram *DebugTranslation::translateImpl(DISubprogramAttr attr) {
  if (auto iter = distinctAttrToNode.find(attr.getId());
      iter != distinctAttrToNode.end())
    return cast<llvm::DISubprogram>(iter->second);

  llvm::DIScope *scope = translate(attr.getScope());
  llvm::DIFile *file = translate(attr.getFile());
  llvm::DIType *type = translate(attr.getType());
  llvm::DICompileUnit *compileUnit = translate(attr.getCompileUnit());

  // Check again after recursive calls in case this distinct node recurses back
  // to itself.
  if (auto iter = distinctAttrToNode.find(attr.getId());
      iter != distinctAttrToNode.end())
    return cast<llvm::DISubprogram>(iter->second);

  bool isDefinition = static_cast<bool>(attr.getSubprogramFlags() &
                                        LLVM::DISubprogramFlags::Definition);

  llvm::DISubprogram *node = getDistinctOrUnique<llvm::DISubprogram>(
      isDefinition, llvmCtx, scope, getMDStringOrNull(attr.getName()),
      getMDStringOrNull(attr.getLinkageName()), file, attr.getLine(), type,
      attr.getScopeLine(),
      /*ContainingType=*/nullptr, /*VirtualIndex=*/0,
      /*ThisAdjustment=*/0, llvm::DINode::FlagZero,
      static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
      compileUnit, /*TemplateParams=*/nullptr, /*Declaration=*/nullptr,
      getMDTupleOrNull(attr.getRetainedNodes()), nullptr,
      getMDTupleOrNull(attr.getAnnotations()));
  if (attr.getId())
    distinctAttrToNode.try_emplace(attr.getId(), node);
  return node;
}

llvm::DIModule *DebugTranslation::translateImpl(DIModuleAttr attr) {
  return llvm::DIModule::get(
      llvmCtx, translate(attr.getFile()), translate(attr.getScope()),
      getMDStringOrNull(attr.getName()),
      getMDStringOrNull(attr.getConfigMacros()),
      getMDStringOrNull(attr.getIncludePath()),
      getMDStringOrNull(attr.getApinotes()), attr.getLine(), attr.getIsDecl());
}

llvm::DINamespace *DebugTranslation::translateImpl(DINamespaceAttr attr) {
  return llvm::DINamespace::get(llvmCtx, translate(attr.getScope()),
                                getMDStringOrNull(attr.getName()),
                                attr.getExportSymbols());
}

llvm::DIImportedEntity *
DebugTranslation::translateImpl(DIImportedEntityAttr attr) {
  return llvm::DIImportedEntity::get(
      llvmCtx, attr.getTag(), translate(attr.getScope()),
      translate(attr.getEntity()), translate(attr.getFile()), attr.getLine(),
      getMDStringOrNull(attr.getName()), getMDTupleOrNull(attr.getElements()));
}

llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) {
  auto getMetadataOrNull = [&](Attribute attr) -> llvm::Metadata * {
    if (!attr)
      return nullptr;

    llvm::Metadata *metadata =
        llvm::TypeSwitch<Attribute, llvm::Metadata *>(attr)
            .Case([&](IntegerAttr intAttr) {
              return llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
                  llvm::Type::getInt64Ty(llvmCtx), intAttr.getInt()));
            })
            .Case([&](LLVM::DIExpressionAttr expr) {
              return translateExpression(expr);
            })
            .Case([&](LLVM::DILocalVariableAttr local) {
              return translate(local);
            })
            .Case<>([&](LLVM::DIGlobalVariableAttr global) {
              return translate(global);
            })
            .Default([&](Attribute attr) { return nullptr; });
    return metadata;
  };
  return llvm::DISubrange::get(llvmCtx, getMetadataOrNull(attr.getCount()),
                               getMetadataOrNull(attr.getLowerBound()),
                               getMetadataOrNull(attr.getUpperBound()),
                               getMetadataOrNull(attr.getStride()));
}

llvm::DICommonBlock *DebugTranslation::translateImpl(DICommonBlockAttr attr) {
  return llvm::DICommonBlock::get(llvmCtx, translate(attr.getScope()),
                                  translate(attr.getDecl()),
                                  getMDStringOrNull(attr.getName()),
                                  translate(attr.getFile()), attr.getLine());
}

llvm::DIGenericSubrange *
DebugTranslation::translateImpl(DIGenericSubrangeAttr attr) {
  auto getMetadataOrNull = [&](Attribute attr) -> llvm::Metadata * {
    if (!attr)
      return nullptr;

    llvm::Metadata *metadata =
        llvm::TypeSwitch<Attribute, llvm::Metadata *>(attr)
            .Case([&](LLVM::DIExpressionAttr expr) {
              return translateExpression(expr);
            })
            .Case([&](LLVM::DILocalVariableAttr local) {
              return translate(local);
            })
            .Case<>([&](LLVM::DIGlobalVariableAttr global) {
              return translate(global);
            })
            .Default([&](Attribute attr) { return nullptr; });
    return metadata;
  };
  return llvm::DIGenericSubrange::get(llvmCtx,
                                      getMetadataOrNull(attr.getCount()),
                                      getMetadataOrNull(attr.getLowerBound()),
                                      getMetadataOrNull(attr.getUpperBound()),
                                      getMetadataOrNull(attr.getStride()));
}

llvm::DISubroutineType *
DebugTranslation::translateImpl(DISubroutineTypeAttr attr) {
  // Concatenate the result and argument types into a single array.
  SmallVector<llvm::Metadata *> types;
  for (DITypeAttr type : attr.getTypes())
    types.push_back(translate(type));
  return llvm::DISubroutineType::get(
      llvmCtx, llvm::DINode::FlagZero, attr.getCallingConvention(),
      llvm::DITypeRefArray(llvm::MDNode::get(llvmCtx, types)));
}

llvm::DIType *DebugTranslation::translateImpl(DITypeAttr attr) {
  return cast<llvm::DIType>(translate(DINodeAttr(attr)));
}

llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
  if (!attr)
    return nullptr;
  // Check for a cached instance.
  if (llvm::DINode *node = attrToNode.lookup(attr))
    return node;

  llvm::DINode *node = nullptr;
  // Recursive types go through a dedicated handler. All other types are
  // dispatched directly to their specific handlers.
  if (auto recTypeAttr = dyn_cast<DIRecursiveTypeAttrInterface>(attr))
    if (recTypeAttr.getRecId())
      node = translateRecursive(recTypeAttr);

  if (!node)
    node = TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
               .Case<DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
                     DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
                     DIGenericSubrangeAttr, DIGlobalVariableAttr,
                     DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
                     DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
                     DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
                     DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
                   [&](auto attr) { return translateImpl(attr); });

  if (node && !node->isTemporary())
    attrToNode.insert({attr, node});
  return node;
}

//===----------------------------------------------------------------------===//
// Locations
//===----------------------------------------------------------------------===//

/// Translate the given location to an llvm debug location.
llvm::DILocation *DebugTranslation::translateLoc(Location loc,
                                                 llvm::DILocalScope *scope) {
  if (!debugEmissionIsEnabled)
    return nullptr;
  return translateLoc(loc, scope, /*inlinedAt=*/nullptr);
}

llvm::DIExpression *
DebugTranslation::translateExpression(LLVM::DIExpressionAttr attr) {
  SmallVector<uint64_t, 1> ops;
  if (attr) {
    // Append operations their operands to the list.
    for (const DIExpressionElemAttr &op : attr.getOperations()) {
      ops.push_back(op.getOpcode());
      append_range(ops, op.getArguments());
    }
  }
  return llvm::DIExpression::get(llvmCtx, ops);
}

llvm::DIGlobalVariableExpression *
DebugTranslation::translateGlobalVariableExpression(
    LLVM::DIGlobalVariableExpressionAttr attr) {
  return llvm::DIGlobalVariableExpression::get(
      llvmCtx, translate(attr.getVar()), translateExpression(attr.getExpr()));
}

/// Translate the given location to an llvm DebugLoc.
llvm::DILocation *DebugTranslation::translateLoc(Location loc,
                                                 llvm::DILocalScope *scope,
                                                 llvm::DILocation *inlinedAt) {
  // LLVM doesn't have a representation for unknown.
  if (isa<UnknownLoc>(loc))
    return nullptr;

  // Check for a cached instance.
  auto existingIt = locationToLoc.find(std::make_tuple(loc, scope, inlinedAt));
  if (existingIt != locationToLoc.end())
    return existingIt->second;

  llvm::DILocation *llvmLoc = nullptr;
  if (auto callLoc = dyn_cast<CallSiteLoc>(loc)) {
    // For callsites, the caller is fed as the inlinedAt for the callee.
    auto *callerLoc = translateLoc(callLoc.getCaller(), scope, inlinedAt);
    // If the caller scope is not translatable, the overall callsite cannot be
    // represented in LLVM (the callee scope may not match the parent function).
    if (!callerLoc) {
      // If there is an inlinedAt scope (an outer caller), skip to that
      // directly. Otherwise, cannot translate.
      if (!inlinedAt)
        return nullptr;
      callerLoc = inlinedAt;
    }
    llvmLoc = translateLoc(callLoc.getCallee(), nullptr, callerLoc);
    // Fallback: Ignore callee if it has no debug scope.
    if (!llvmLoc)
      llvmLoc = callerLoc;

  } else if (auto fileLoc = dyn_cast<FileLineColLoc>(loc)) {
    // A scope of a DILocation cannot be null.
    if (!scope)
      return nullptr;
    llvmLoc =
        llvm::DILocation::get(llvmCtx, fileLoc.getLine(), fileLoc.getColumn(),
                              scope, const_cast<llvm::DILocation *>(inlinedAt));

  } else if (auto fusedLoc = dyn_cast<FusedLoc>(loc)) {
    ArrayRef<Location> locations = fusedLoc.getLocations();

    // Check for a scope encoded with the location.
    if (auto scopedAttr =
            dyn_cast_or_null<LLVM::DILocalScopeAttr>(fusedLoc.getMetadata()))
      scope = translate(scopedAttr);

    // For fused locations, merge each of the nodes.
    llvmLoc = translateLoc(locations.front(), scope, inlinedAt);
    for (Location locIt : locations.drop_front()) {
      llvmLoc = llvm::DILocation::getMergedLocation(
          llvmLoc, translateLoc(locIt, scope, inlinedAt));
    }

  } else if (auto nameLoc = dyn_cast<NameLoc>(loc)) {
    llvmLoc = translateLoc(nameLoc.getChildLoc(), scope, inlinedAt);

  } else if (auto opaqueLoc = dyn_cast<OpaqueLoc>(loc)) {
    llvmLoc = translateLoc(opaqueLoc.getFallbackLocation(), scope, inlinedAt);
  } else {
    llvm_unreachable("unknown location kind");
  }

  locationToLoc.try_emplace(std::make_tuple(loc, scope, inlinedAt), llvmLoc);
  return llvmLoc;
}

/// Create an llvm debug file for the given file path.
llvm::DIFile *DebugTranslation::translateFile(StringRef fileName) {
  auto *&file = fileMap[fileName];
  if (file)
    return file;

  // Make sure the current working directory is up-to-date.
  if (currentWorkingDir.empty())
    llvm::sys::fs::current_path(currentWorkingDir);

  StringRef directory = currentWorkingDir;
  SmallString<128> dirBuf;
  SmallString<128> fileBuf;
  if (llvm::sys::path::is_absolute(fileName)) {
    // Strip the common prefix (if it is more than just "/") from current
    // directory and FileName for a more space-efficient encoding.
    auto fileIt = llvm::sys::path::begin(fileName);
    auto fileE = llvm::sys::path::end(fileName);
    auto curDirIt = llvm::sys::path::begin(directory);
    auto curDirE = llvm::sys::path::end(directory);
    for (; curDirIt != curDirE && *curDirIt == *fileIt; ++curDirIt, ++fileIt)
      llvm::sys::path::append(dirBuf, *curDirIt);
    if (std::distance(llvm::sys::path::begin(directory), curDirIt) == 1) {
      // Don't strip the common prefix if it is only the root "/"  since that
      // would make LLVM diagnostic locations confusing.
      directory = StringRef();
    } else {
      for (; fileIt != fileE; ++fileIt)
        llvm::sys::path::append(fileBuf, *fileIt);
      directory = dirBuf;
      fileName = fileBuf;
    }
  }
  return (file = llvm::DIFile::get(llvmCtx, fileName, directory));
}
