//===- 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/SmallVectorExtras.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.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;
}

static constexpr StringRef kDebugVersionKey = "Debug Info Version";
static constexpr StringRef kCodeViewKey = "CodeView";

void DebugTranslation::addModuleFlagsIfNotPresent() {
  // TODO: The version information should be encoded on the LLVM module itself,
  // not implicitly set here.

  // Mark this module as having debug information.
  if (!llvmModule.getModuleFlag(kDebugVersionKey))
    llvmModule.addModuleFlag(llvm::Module::Warning, kDebugVersionKey,
                             llvm::DEBUG_METADATA_VERSION);

  const llvm::Triple &targetTriple = llvmModule.getTargetTriple();
  if (targetTriple.isKnownWindowsMSVCEnvironment()) {
    // Dwarf debugging files will be generated by default, unless "CodeView"
    // is set explicitly. Windows/MSVC should use CodeView instead.
    if (!llvmModule.getModuleFlag(kCodeViewKey))
      llvmModule.addModuleFlag(llvm::Module::Warning, kCodeViewKey, 1);
  }
}

/// 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::map_to_vector(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::MDTuple *
DebugTranslation::getRetainedNodesOrNull(ArrayRef<Attribute> retainedNodes) {
  if (retainedNodes.empty())
    return nullptr;
  SmallVector<llvm::Metadata *> llvmElements = llvm::map_to_vector(
      retainedNodes, [&](Attribute attr) -> llvm::Metadata * {
        if (auto GVE = dyn_cast<DIGlobalVariableExpressionAttr>(attr))
          return translateGlobalVariableExpression(GVE);

        auto diAttr = dyn_cast<DINodeAttr>(attr);
        if (!diAttr)
          llvm_unreachable("unknown retained node kind");
        return translate(diAttr);
      });
  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);
}

static llvm::DISourceLanguageName getSourceLanguage(DICompileUnitAttr attr) {
  DISourceLanguageNameAttr sourceLanguage = attr.getSourceLanguage();
  // A DW_LNAME value selects the versioned source-language representation;
  // otherwise, the value is an unversioned DW_LANG value.
  if (sourceLanguage.getName())
    return llvm::DISourceLanguageName(
        static_cast<uint16_t>(sourceLanguage.getName()),
        *sourceLanguage.getVersion(),
        static_cast<uint16_t>(sourceLanguage.getDialect()));
  return llvm::DISourceLanguageName(
      static_cast<uint16_t>(sourceLanguage.getLanguage()),
      static_cast<uint16_t>(sourceLanguage.getDialect()));
}

llvm::TempDICompileUnit
DebugTranslation::translateTemporaryImpl(DICompileUnitAttr attr) {
  return llvm::DICompileUnit::getTemporary(
      llvmCtx, getSourceLanguage(attr),
      /*File=*/nullptr, "", attr.getIsOptimized(),
      /*Flags=*/"", /*RuntimeVersion=*/0,
      /*splitDebugFileName=*/"",
      static_cast<llvm::DICompileUnit::DebugEmissionKind>(
          attr.getEmissionKind()),
      /*EnumTypes=*/nullptr, /*RetainedTypes=*/nullptr,
      /*GlobalVariables=*/nullptr, /*ImportedEntities=*/nullptr,
      /*Macros=*/nullptr,
      /*DWOId=*/0, /*SplitDebugInlining=*/true,
      attr.getIsDebugInfoForProfiling(),
      static_cast<llvm::DICompileUnit::DebugNameTableKind>(
          attr.getNameTableKind()),
      /*RangesBaseAddress=*/false, /*SysRoot=*/"", /*SDK=*/"");
}

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

  llvm::DIBuilder builder(llvmModule);
  llvm::DICompileUnit *cu = builder.createCompileUnit(
      getSourceLanguage(attr), translate(attr.getFile()),
      attr.getProducer() ? attr.getProducer().getValue() : "",
      attr.getIsOptimized(),
      /*Flags=*/"", /*RV=*/0,
      attr.getSplitDebugFilename() ? attr.getSplitDebugFilename().getValue()
                                   : "",
      static_cast<llvm::DICompileUnit::DebugEmissionKind>(
          attr.getEmissionKind()),
      0, true, attr.getIsDebugInfoForProfiling(),
      static_cast<llvm::DICompileUnit::DebugNameTableKind>(
          attr.getNameTableKind()));

  llvm::SmallVector<llvm::Metadata *> importNodes;
  for (DINodeAttr importNode : attr.getImportedEntities())
    importNodes.push_back(translate(importNode));
  if (!importNodes.empty())
    cu->replaceImportedEntities(llvm::MDTuple::get(llvmCtx, importNodes));

  if (attr.getId())
    distinctAttrToNode.try_emplace(attr.getId(), cu);

  return cu;
}

/// 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, /*EnumKind=*/std::nullopt,
      /*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:
  case llvm::dwarf::DW_TAG_variant_part:
    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, /*EnumKind*/ std::nullopt, /*VTableHolder=*/nullptr,
      /*TemplateParams=*/nullptr, getMDStringOrNull(attr.getIdentifier()),
      translate(attr.getDiscriminator()),
      getExpressionAttrOrNull(attr.getDataLocation()),
      getExpressionAttrOrNull(attr.getAssociated()),
      getExpressionAttrOrNull(attr.getAllocated()),
      getExpressionAttrOrNull(attr.getRank()));
}

llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) {
  llvm::Metadata *extraData = nullptr;
  if (Attribute extraDataAttr = attr.getExtraData()) {
    extraData =
        llvm::TypeSwitch<Attribute, llvm::Metadata *>(extraDataAttr)
            .Case([&](DINodeAttr nodeAttr) { return translate(nodeAttr); })
            .Case([&](IntegerAttr intAttr) {
              return llvm::ConstantAsMetadata::get(
                  llvm::ConstantInt::get(llvmCtx, intAttr.getValue()));
            })
            .Default([](Attribute) -> llvm::Metadata * {
              llvm_unreachable("verifier guarantees DINodeAttr or IntegerAttr");
            });
  }

  return llvm::DIDerivedType::get(
      llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()),
      translate(attr.getFile()), attr.getLine(), translate(attr.getScope()),
      translate(attr.getBaseType()), attr.getSizeInBits(),
      attr.getAlignInBits(), attr.getOffsetInBits(),
      attr.getDwarfAddressSpace(), /*PtrAuthData=*/std::nullopt,
      /*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()), extraData);
}

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(),
                            /*Column=*/0, /*IsArtificial=*/false,
                            /*CoroSuspendIdx=*/std::nullopt);
}

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 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 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([&](DICompileUnitAttr attr) {
            auto temporary = translateTemporaryImpl(attr);
            setRecursivePlaceholder(temporary.get());
            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,
      getRetainedNodesOrNull(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(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(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::DITypeArray(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));
}
