//===--- IRGenDebugInfo.cpp - Debug Info Support --------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file implements IR debug info generation for Swift.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "debug-info"
#include "IRGenDebugInfo.h"
#include "GenOpaque.h"
#include "GenStruct.h"
#include "GenType.h"
#include "swift/AST/ASTMangler.h"
#include "swift/AST/Expr.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/AST/Module.h"
#include "swift/AST/ModuleLoader.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/TypeDifferenceVisitor.h"
#include "swift/Basic/Dwarf.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Basic/Version.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/ClangImporter/ClangModule.h"
#include "swift/Demangling/ManglingMacros.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILModule.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Local.h"

#ifndef NDEBUG
#include "swift/AST/ASTDemangler.h"
#endif

using namespace swift;
using namespace irgen;

llvm::cl::opt<bool> VerifyLineTable(
    "verify-linetable", llvm::cl::init(false),
    llvm::cl::desc(
        "Verify that the debug locations within one scope are contiguous."));

namespace {
using TrackingDIRefMap =
    llvm::DenseMap<const llvm::MDString *, llvm::TrackingMDNodeRef>;

class EqualUpToClangTypes
    : public CanTypeDifferenceVisitor<EqualUpToClangTypes> {
public:
  bool visitDifferentTypeStructure(CanType t1, CanType t2) {
#define COMPARE_UPTO_CLANG_TYPE(CLASS)                                         \
  if (auto f1 = dyn_cast<CLASS>(t1)) {                                         \
    auto f2 = cast<CLASS>(t2);                                                 \
    return !f1->getExtInfo().isEqualTo(f2->getExtInfo(),                       \
                                       /*useClangTypes*/ false);               \
  }
    COMPARE_UPTO_CLANG_TYPE(FunctionType);
    COMPARE_UPTO_CLANG_TYPE(SILFunctionType);
#undef COMPARE_UPTO_CLANG_TYPE
    return true;
  }
  bool check(Type t1, Type t2) {
    return !visit(t1->getCanonicalType(), t2->getCanonicalType());
  };
};

static bool equalWithoutExistentialTypes(Type t1, Type t2) {
  if (!t1->getASTContext().LangOpts.EnableExplicitExistentialTypes)
    return false;

  auto withoutExistentialTypes = [](Type type) -> Type {
    return type.transform([](Type type) -> Type {
      if (auto existential = type->getAs<ExistentialType>())
        return existential->getConstraintType();
      return type;
    });
  };

  return withoutExistentialTypes(t1)
      ->isEqual(withoutExistentialTypes(t2));
}

class IRGenDebugInfoImpl : public IRGenDebugInfo {
  friend class IRGenDebugInfoImpl;
  const IRGenOptions &Opts;
  ClangImporter &CI;
  SourceManager &SM;
  llvm::Module &M;
  llvm::DIBuilder DBuilder;
  IRGenModule &IGM;
  const PathRemapper &DebugPrefixMap;

  /// Various caches.
  /// \{
  llvm::StringSet<> VarNames;
  using VarID = std::tuple<llvm::MDNode *, llvm::StringRef, unsigned, uint16_t>;
  llvm::DenseMap<VarID, llvm::TrackingMDNodeRef> LocalVarCache;
  llvm::DenseMap<const SILDebugScope *, llvm::TrackingMDNodeRef> ScopeCache;
  llvm::DenseMap<const SILDebugScope *, llvm::TrackingMDNodeRef> InlinedAtCache;
  llvm::DenseMap<const void *, SILLocation::FilenameAndLocation>
     FilenameAndLocationCache;
  llvm::DenseMap<TypeBase *, llvm::TrackingMDNodeRef> DITypeCache;
  llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
  llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
  TrackingDIRefMap DIRefMap;
  TrackingDIRefMap InnerTypeCache;
  /// \}

  /// A list of replaceable fwddecls that need to be RAUWed at the end.
  std::vector<std::pair<TypeBase *, llvm::TrackingMDRef>> ReplaceMap;
  /// The set of imported modules.
  llvm::DenseSet<ModuleDecl *> ImportedModules;

  llvm::BumpPtrAllocator DebugInfoNames;
  /// The current working directory.
  StringRef CWDName;
  /// User-provided -D macro definitions.
  SmallString<0> ConfigMacros;
  /// The current compilation unit.
  llvm::DICompileUnit *TheCU = nullptr;
  /// The main file.
  llvm::DIFile *MainFile = nullptr;
  /// The current module.
  llvm::DIModule *MainModule = nullptr;
  /// Scope of entry point function (main by default).
  llvm::DIScope *EntryPointFn = nullptr;
  /// The artificial type decls for named archetypes.
  llvm::StringMap<TypeAliasDecl *> MetadataTypeDeclCache;
  /// Catch-all type for opaque internal types.
  llvm::DIType *InternalType = nullptr;

  /// The last location that was emitted.
  SILLocation::FilenameAndLocation LastFilenameAndLocation;
  /// The scope of that last location.
  const SILDebugScope *LastScope = nullptr;

  /// Used by pushLoc.
  SmallVector<std::pair<SILLocation::FilenameAndLocation, const SILDebugScope *>, 8>
      LocationStack;

#ifndef NDEBUG
  using UUSTuple = std::pair<std::pair<unsigned, unsigned>, StringRef>;
  struct FilenameAndLocationKey : public UUSTuple {
    FilenameAndLocationKey(SILLocation::FilenameAndLocation DL)
        : UUSTuple({{DL.line, DL.column}, DL.filename}) {}
    inline bool operator==(const SILLocation::FilenameAndLocation &DL) const {
      return first.first == DL.line && first.second == DL.column &&
             second.equals(DL.filename);
    }
  };
  llvm::DenseSet<UUSTuple> PreviousLineEntries;
  SILLocation::FilenameAndLocation PreviousFilenameAndLocation;
#endif

public:
  IRGenDebugInfoImpl(const IRGenOptions &Opts, ClangImporter &CI,
                     IRGenModule &IGM, llvm::Module &M,
                     StringRef MainOutputFilenameForDebugInfo,
                     StringRef PrivateDiscriminator);
  void finalize();

  void setCurrentLoc(IRBuilder &Builder, const SILDebugScope *DS,
                     SILLocation Loc);

  void addFailureMessageToCurrentLoc(IRBuilder &Builder, StringRef failureMsg);

  void clearLoc(IRBuilder &Builder);
  void pushLoc();
  void popLoc();
  void setInlinedTrapLocation(IRBuilder &Builder, const SILDebugScope *Scope);
  void setEntryPointLoc(IRBuilder &Builder);
  llvm::DIScope *getEntryPointFn();
  llvm::DIScope *getOrCreateScope(const SILDebugScope *DS);
  void emitImport(ImportDecl *D);
  llvm::DISubprogram *emitFunction(const SILDebugScope *DS, llvm::Function *Fn,
                                   SILFunctionTypeRepresentation Rep,
                                   SILType Ty, DeclContext *DeclCtx = nullptr);
  llvm::DISubprogram *emitFunction(SILFunction &SILFn, llvm::Function *Fn);
  void emitArtificialFunction(IRBuilder &Builder, llvm::Function *Fn,
                              SILType SILTy);

  /// Return false if we fail to create the right DW_OP_LLVM_fragment operand.
  bool handleFragmentDIExpr(const SILDIExprOperand &CurDIExprOp,
                            SmallVectorImpl<uint64_t> &Operands);
  /// Return false if we fail to create the desired !DIExpression.
  bool buildDebugInfoExpression(const SILDebugVariable &VarInfo,
                                SmallVectorImpl<uint64_t> &Operands);

  void emitVariableDeclaration(IRBuilder &Builder,
                               ArrayRef<llvm::Value *> Storage,
                               DebugTypeInfo Ty, const SILDebugScope *DS,
                               Optional<SILLocation> VarLoc,
                               SILDebugVariable VarInfo,
                               IndirectionKind = DirectValue,
                               ArtificialKind = RealValue);
  void emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
                        llvm::DILocalVariable *Var, llvm::DIExpression *Expr,
                        unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
                        const SILDebugScope *DS, bool InCoroContext);

  void emitGlobalVariableDeclaration(llvm::GlobalVariable *Storage,
                                     StringRef Name, StringRef LinkageName,
                                     DebugTypeInfo DebugType,
                                     bool IsLocalToUnit, bool InFixedBuffer,
                                     Optional<SILLocation> Loc);
  void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
                        unsigned Depth, unsigned Index, StringRef Name);

  /// Return the DIBuilder.
  llvm::DIBuilder &getBuilder() { return DBuilder; }

  /// Decode (and cache) a SourceLoc.
  SILLocation::FilenameAndLocation decodeSourceLoc(SourceLoc SL);

  IRGenDebugInfoFormat getDebugInfoFormat() { return Opts.DebugInfoFormat; }

private:
  static StringRef getFilenameFromDC(const DeclContext *DC) {
    if (auto *LF = dyn_cast<LoadedFile>(DC))
      return LF->getFilename();
    if (auto *SF = dyn_cast<SourceFile>(DC))
      return SF->getFilename();
    if (auto *M = dyn_cast<ModuleDecl>(DC))
      return M->getModuleFilename();
    return {};
  }

  using FilenameAndLocation = SILLocation::FilenameAndLocation;
  FilenameAndLocation getDeserializedLoc(Pattern *) { return {}; }
  FilenameAndLocation getDeserializedLoc(Expr *) { return {}; }
  FilenameAndLocation getDeserializedLoc(Decl *D) {
    FilenameAndLocation L;
    const DeclContext *DC = D->getDeclContext()->getModuleScopeContext();
    StringRef Filename = getFilenameFromDC(DC);
    if (!Filename.empty())
      L.filename = Filename;
    return L;
  }

  /// Use the Swift SM to figure out the actual line/column of a SourceLoc.
  template <typename WithLoc>
  FilenameAndLocation getSwiftFilenameAndLocation(IRGenDebugInfo &DI,
                                                  WithLoc *ASTNode, bool End) {
    if (!ASTNode)
      return {};

    SourceLoc Loc = End ? ASTNode->getEndLoc() : ASTNode->getStartLoc();
    if (Loc.isInvalid())
      // This may be a deserialized or clang-imported decl. And modules
      // don't come with SourceLocs right now. Get at least the name of
      // the module.
      return getDeserializedLoc(ASTNode);

    return DI.decodeSourceLoc(Loc);
  }

  FilenameAndLocation getFilenameAndLocation(IRGenDebugInfo &DI, Pattern *P,
                                             bool End = false) {
    return getSwiftFilenameAndLocation(DI, P, End);
  }
  FilenameAndLocation getFilenameAndLocation(IRGenDebugInfo &DI, Expr *E,
                                             bool End = false) {
    return getSwiftFilenameAndLocation(DI, E, End);
  }
  FilenameAndLocation getFilenameAndLocation(IRGenDebugInfo &DI, Decl *D,
                                             bool End = false) {
    FilenameAndLocation L;
    if (!D)
      return L;

    if (auto *ClangDecl = D->getClangDecl()) {
      clang::SourceLocation ClangSrcLoc = ClangDecl->getBeginLoc();
      clang::SourceManager &ClangSM =
          CI.getClangASTContext().getSourceManager();
      clang::PresumedLoc PresumedLoc = ClangSM.getPresumedLoc(ClangSrcLoc);
      if (!PresumedLoc.isValid())
        return L;
      L.line = PresumedLoc.getLine();
      L.column = PresumedLoc.getColumn();
      L.filename = PresumedLoc.getFilename();
      return L;
    }
    return getSwiftFilenameAndLocation(DI, D, End);
  }

  FilenameAndLocation getStartLocation(Optional<SILLocation> OptLoc) {
    if (!OptLoc)
      return {};
    if (OptLoc->isFilenameAndLocation())
      return sanitizeCodeViewFilenameAndLocation(*OptLoc->getFilenameAndLocation());
    return decodeSourceLoc(OptLoc->getStartSourceLoc());
  }

  FilenameAndLocation sanitizeCodeViewFilenameAndLocation(FilenameAndLocation DLoc) {
    if (Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView)
      // When WinDbg finds two locations with the same line but different
      // columns, the user must select an address when they break on that
      // line. Also, clang does not emit column locations in CodeView for C++.
      DLoc.column = 0;
    return DLoc;
  }

  FilenameAndLocation decodeFilenameAndLocation(SILLocation Loc) {
    if (Loc.isFilenameAndLocation())
      return sanitizeCodeViewFilenameAndLocation(*Loc.getFilenameAndLocation());
    return decodeSourceLoc(Loc.getSourceLocForDebugging());
  }

  /// Strdup a raw char array using the bump pointer.
  StringRef BumpAllocatedString(const char *Data, size_t Length) {
    char *Ptr = DebugInfoNames.Allocate<char>(Length + 1);
    memcpy(Ptr, Data, Length);
    *(Ptr + Length) = 0;
    return StringRef(Ptr, Length);
  }

  /// Strdup S using the bump pointer.
  StringRef BumpAllocatedString(std::string S) {
    return BumpAllocatedString(S.c_str(), S.length());
  }

  /// Strdup StringRef S using the bump pointer.
  StringRef BumpAllocatedString(StringRef S) {
    return BumpAllocatedString(S.data(), S.size());
  }

  /// Return the size reported by a type.
  static unsigned getSizeInBits(llvm::DIType *Ty) {
    // Follow derived types until we reach a type that
    // reports back a size.
    while (isa<llvm::DIDerivedType>(Ty) && !Ty->getSizeInBits()) {
      auto *DT = cast<llvm::DIDerivedType>(Ty);
      Ty = DT->getBaseType();
      if (!Ty)
        return 0;
    }
    return Ty->getSizeInBits();
  }

#ifndef NDEBUG

  /// Return the size reported by the variable's type.
  static unsigned getSizeInBits(const llvm::DILocalVariable *Var) {
    llvm::DIType *Ty = Var->getType();
    return getSizeInBits(Ty);
  }

#endif

  /// Determine whether this debug scope belongs to an explicit closure.
  static bool isExplicitClosure(const SILFunction *SILFn) {
    if (SILFn && SILFn->hasLocation())
      if (Expr *E = SILFn->getLocation().getAsASTNode<Expr>())
        if (isa<ClosureExpr>(E))
          return true;
    return false;
  }

  llvm::MDNode *createInlinedAt(const SILDebugScope *DS) {
    auto *CS = DS->InlinedCallSite;
    if (!CS)
      return nullptr;

    auto CachedInlinedAt = InlinedAtCache.find(CS);
    if (CachedInlinedAt != InlinedAtCache.end())
      return cast<llvm::MDNode>(CachedInlinedAt->second);

    auto L = decodeFilenameAndLocation(CS->Loc);
    auto Scope = getOrCreateScope(CS->Parent.dyn_cast<const SILDebugScope *>());
    // Pretend transparent functions don't exist.
    if (!Scope)
      return createInlinedAt(CS);
    auto InlinedAt = llvm::DILocation::get(
        IGM.getLLVMContext(), L.line, L.column, Scope, createInlinedAt(CS));
    InlinedAtCache.insert({CS, llvm::TrackingMDNodeRef(InlinedAt)});
    return InlinedAt;
  }

#ifndef NDEBUG
  /// Perform a couple of sanity checks on scopes.
  static bool parentScopesAreSane(const SILDebugScope *DS) {
    auto *Parent = DS;
    while ((Parent = Parent->Parent.dyn_cast<const SILDebugScope *>())) {
      if (!DS->InlinedCallSite)
        assert(!Parent->InlinedCallSite &&
               "non-inlined scope has an inlined parent");
    }
    return true;
  }

  /// Assert that within one lexical block, each location is only visited once.
  bool lineEntryIsSane(FilenameAndLocation DL, const SILDebugScope *DS);

#endif

  llvm::DIFile *getOrCreateFile(StringRef Filename) {
    if (Filename.empty())
      Filename = SILLocation::getCompilerGeneratedLoc()->filename;

    // Look in the cache first.
    auto CachedFile = DIFileCache.find(Filename);
    if (CachedFile != DIFileCache.end()) {
      // Verify that the information still exists.
      if (llvm::Metadata *V = CachedFile->second)
        return cast<llvm::DIFile>(V);
    }

    // Detect the main file.
    StringRef MainFileName = MainFile->getFilename();
    if (MainFile && Filename.endswith(MainFileName)) {
      SmallString<256> AbsThisFile, AbsMainFile;
      AbsThisFile = Filename;
      llvm::sys::fs::make_absolute(AbsThisFile);
      if (llvm::sys::path::is_absolute(MainFileName))
        AbsMainFile = MainFileName;
      else
        llvm::sys::path::append(AbsMainFile, MainFile->getDirectory(),
                                MainFileName);
      if (AbsThisFile == DebugPrefixMap.remapPath(AbsMainFile)) {
        DIFileCache[Filename] = llvm::TrackingMDNodeRef(MainFile);
        return MainFile;
      }
    }

    return createFile(Filename, None, None);
  }

  /// This is effectively \p clang::CGDebugInfo::createFile().
  llvm::DIFile *
  createFile(StringRef FileName,
             Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
             Optional<StringRef> Source) {
    StringRef File, Dir;
    StringRef CurDir = Opts.DebugCompilationDir;
    SmallString<128> NormalizedFile(FileName);
    SmallString<128> FileBuf, DirBuf;
    llvm::sys::path::remove_dots(NormalizedFile);
    if (llvm::sys::path::is_absolute(NormalizedFile) &&
        llvm::sys::path::is_absolute(CurDir)) {
      // 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(NormalizedFile);
      auto FileE = llvm::sys::path::end(NormalizedFile);
      auto CurDirIt = llvm::sys::path::begin(CurDir);
      auto CurDirE = llvm::sys::path::end(CurDir);
      for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
        llvm::sys::path::append(DirBuf, *CurDirIt);
      if (std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) {
        // Don't strip the common prefix if it is only the root "/"
        // since that would make LLVM diagnostic locations confusing.
        Dir = {};
        File = NormalizedFile;
      } else {
        for (; FileIt != FileE; ++FileIt)
          llvm::sys::path::append(FileBuf, *FileIt);
        Dir = DirBuf;
        File = FileBuf;
      }
    } else {
      File = NormalizedFile;
      // Leave <compiler-generated> & friends as is, without directory.
      if (!(File.startswith("<") && File.endswith(">")))
        Dir = CurDir;
    }
    llvm::DIFile *F =
        DBuilder.createFile(DebugPrefixMap.remapPath(File),
                            DebugPrefixMap.remapPath(Dir), CSInfo, Source);
    DIFileCache[FileName].reset(F);
    return F;
  }

  StringRef getName(const FuncDecl &FD) {
    // Getters and Setters are anonymous functions, so we forge a name
    // using its parent declaration.
    if (auto accessor = dyn_cast<AccessorDecl>(&FD))
      if (ValueDecl *VD = accessor->getStorage()) {
        const char *Kind;
        switch (accessor->getAccessorKind()) {
        case AccessorKind::Get:
          Kind = ".get";
          break;
        case AccessorKind::Set:
          Kind = ".set";
          break;
        case AccessorKind::WillSet:
          Kind = ".willset";
          break;
        case AccessorKind::DidSet:
          Kind = ".didset";
          break;
        case AccessorKind::Address:
          Kind = ".addressor";
          break;
        case AccessorKind::MutableAddress:
          Kind = ".mutableAddressor";
          break;
        case AccessorKind::Read:
          Kind = ".read";
          break;
        case AccessorKind::Modify:
          Kind = ".modify";
          break;
        }

        SmallVector<char, 64> Buf;
        StringRef Name =
            (VD->getBaseName().userFacingName() + Twine(Kind)).toStringRef(Buf);
        return BumpAllocatedString(Name);
      }

    if (FD.hasName())
      return FD.getBaseIdentifier().str();

    return StringRef();
  }

  StringRef getName(SILLocation L) {
    if (L.isNull())
      return StringRef();

    if (FuncDecl *FD = L.getAsASTNode<FuncDecl>())
      return getName(*FD);

    if (L.isASTNode<ConstructorDecl>())
      return "init";

    if (L.isASTNode<DestructorDecl>())
      return "deinit";

    return StringRef();
  }

  static CanSILFunctionType getFunctionType(SILType SILTy) {
    if (!SILTy)
      return CanSILFunctionType();

    auto FnTy = SILTy.getAs<SILFunctionType>();
    if (!FnTy) {
      LLVM_DEBUG(llvm::dbgs() << "Unexpected function type: ";
                 SILTy.print(llvm::dbgs()); llvm::dbgs() << "\n");
      return CanSILFunctionType();
    }

    return FnTy;
  }

  llvm::DIScope *getOrCreateContext(DeclContext *DC) {
    if (!DC)
      return TheCU;

    if (isa<FuncDecl>(DC))
      if (auto *Decl = IGM.getSILModule().lookUpFunction(SILDeclRef(
              cast<AbstractFunctionDecl>(DC), SILDeclRef::Kind::Func)))
        return getOrCreateScope(Decl->getDebugScope());

    switch (DC->getContextKind()) {
    // The interesting cases are already handled above.
    case DeclContextKind::AbstractFunctionDecl:
    case DeclContextKind::AbstractClosureExpr:

    // We don't model these in DWARF.
    case DeclContextKind::SerializedLocal:
    case DeclContextKind::Initializer:
    case DeclContextKind::ExtensionDecl:
    case DeclContextKind::SubscriptDecl:
    case DeclContextKind::EnumElementDecl:
    case DeclContextKind::TopLevelCodeDecl:
      return getOrCreateContext(DC->getParent());

    case DeclContextKind::Module:
      return getOrCreateModule(
          {ImportPath::Access(), cast<ModuleDecl>(DC)});
    case DeclContextKind::FileUnit:
      // A module may contain multiple files.
      return getOrCreateContext(DC->getParent());
    case DeclContextKind::GenericTypeDecl: {
      auto *NTD = cast<NominalTypeDecl>(DC);
      auto *Ty = NTD->getDeclaredType().getPointer();
      if (auto *DITy = getTypeOrNull(Ty))
        return DITy;

      // Create a Forward-declared type.
      auto Loc = getFilenameAndLocation(*this, NTD);
      auto File = getOrCreateFile(Loc.filename);
      // No line numbers are attached to type forward declarations.
      auto Line = 0;
      auto FwdDecl = DBuilder.createReplaceableCompositeType(
          llvm::dwarf::DW_TAG_structure_type, NTD->getName().str(),
          getOrCreateContext(DC->getParent()), File, Line,
          llvm::dwarf::DW_LANG_Swift, 0, 0);
      ReplaceMap.emplace_back(
          std::piecewise_construct, std::make_tuple(Ty),
          std::make_tuple(static_cast<llvm::Metadata *>(FwdDecl)));
      return FwdDecl;
    }
    }
    return TheCU;
  }

  void createParameterType(llvm::SmallVectorImpl<llvm::Metadata *> &Parameters,
                           SILType type) {
    auto RealType = type.getASTType();
    auto DbgTy = DebugTypeInfo::getFromTypeInfo(RealType, IGM.getTypeInfo(type),
                                                /*isFragment*/ false);
    Parameters.push_back(getOrCreateType(DbgTy));
  }

  // This is different from SILFunctionType::getAllResultsType() in some subtle
  // ways.
  static SILType getResultTypeForDebugInfo(IRGenModule &IGM,
                                           CanSILFunctionType fnTy) {
    if (fnTy->getNumResults() == 1) {
      return fnTy->getResults()[0].getSILStorageType(
          IGM.getSILModule(), fnTy, IGM.getMaximalTypeExpansionContext());
    } else if (!fnTy->getNumIndirectFormalResults()) {
      return fnTy->getDirectFormalResultsType(
          IGM.getSILModule(), IGM.getMaximalTypeExpansionContext());
    } else {
      SmallVector<TupleTypeElt, 4> eltTys;
      for (auto &result : fnTy->getResults()) {
        eltTys.push_back(result.getReturnValueType(
            IGM.getSILModule(), fnTy, IGM.getMaximalTypeExpansionContext()));
      }
      return SILType::getPrimitiveAddressType(
          CanType(TupleType::get(eltTys, fnTy->getASTContext())));
    }
  }

  llvm::DITypeRefArray createParameterTypes(SILType SILTy) {
    if (!SILTy)
      return nullptr;
    return createParameterTypes(SILTy.castTo<SILFunctionType>());
  }

  llvm::DITypeRefArray createParameterTypes(CanSILFunctionType FnTy) {
    SmallVector<llvm::Metadata *, 16> Parameters;

    GenericContextScope scope(IGM, FnTy->getInvocationGenericSignature());

    // The function return type is the first element in the list.
    createParameterType(Parameters, getResultTypeForDebugInfo(IGM, FnTy));

    // Actually, the input type is either a single type or a tuple
    // type. We currently represent a function with one n-tuple argument
    // as an n-ary function.
    for (auto Param : FnTy->getParameters())
      createParameterType(
          Parameters, IGM.silConv.getSILType(
                          Param, FnTy, IGM.getMaximalTypeExpansionContext()));

    return DBuilder.getOrCreateTypeArray(Parameters);
  }

  /// FIXME: replace this condition with something more sane.
  static bool isAllocatingConstructor(SILFunctionTypeRepresentation Rep,
                                      DeclContext *DeclCtx) {
    return Rep != SILFunctionTypeRepresentation::Method && DeclCtx &&
           isa<ConstructorDecl>(DeclCtx);
  }

  void createImportedModule(llvm::DIScope *Context,
                            ImportedModule M, llvm::DIFile *File,
                            unsigned Line) {
    // For overlays of Clang modules also emit an import of the underlying Clang
    // module. The helps the debugger resolve types that are present only in the
    // underlying module.
    if (const clang::Module *UnderlyingClangModule =
            M.importedModule->findUnderlyingClangModule()) {
      DBuilder.createImportedModule(
          Context,
          getOrCreateModule(
              {*const_cast<clang::Module *>(UnderlyingClangModule)},
              UnderlyingClangModule),
          File, 0);
    }
    DBuilder.createImportedModule(Context, getOrCreateModule(M), File, Line);
  }

  llvm::DIModule *getOrCreateModule(const void *Key, llvm::DIScope *Parent,
                                    StringRef Name, StringRef IncludePath,
                                    uint64_t Signature = ~1ULL,
                                    StringRef ASTFile = StringRef()) {
    // Look in the cache first.
    auto Val = DIModuleCache.find(Key);
    if (Val != DIModuleCache.end())
      return cast<llvm::DIModule>(Val->second);

    std::string RemappedIncludePath = DebugPrefixMap.remapPath(IncludePath);

    // For Clang modules / PCH, create a Skeleton CU pointing to the PCM/PCH.
    if (!Opts.DisableClangModuleSkeletonCUs) {
      bool CreateSkeletonCU = !ASTFile.empty();
      bool IsRootModule = !Parent;
      if (CreateSkeletonCU && IsRootModule) {
        llvm::DIBuilder DIB(M);
        DIB.createCompileUnit(IGM.ObjCInterop ? llvm::dwarf::DW_LANG_ObjC
                                              : llvm::dwarf::DW_LANG_C99,
                              DIB.createFile(Name, RemappedIncludePath),
                              TheCU->getProducer(), true, StringRef(), 0,
                              ASTFile, llvm::DICompileUnit::FullDebug,
                              Signature);
        DIB.finalize();
      }
    }

    llvm::DIModule *M =
        DBuilder.createModule(Parent, Name, ConfigMacros, RemappedIncludePath);
    DIModuleCache.insert({Key, llvm::TrackingMDNodeRef(M)});
    return M;
  }

  using ASTSourceDescriptor = clang::ASTSourceDescriptor;
  /// Create a DIModule from a clang module or PCH.
  /// The clang::Module pointer is passed separately because the recursive case
  /// needs to fudge the AST descriptor.
  llvm::DIModule *getOrCreateModule(ASTSourceDescriptor Desc,
                                    const clang::Module *ClangModule) {
    // PCH files don't have a signature field in the control block,
    // but LLVM detects skeleton CUs by looking for a non-zero DWO id.
    // We use the lower 64 bits for debug info.
    uint64_t Signature =
      Desc.getSignature() ? Desc.getSignature().truncatedValue() : ~1ULL;

    // Handle Clang modules.
    if (ClangModule) {
      llvm::DIModule *Parent = nullptr;
      if (ClangModule->Parent) {
        // The loading of additional modules by Sema may trigger an out-of-date
        // PCM rebuild in the Clang module dependencies of the additional
        // module. A PCM rebuild causes the ModuleManager to unload previously
        // loaded ASTFiles. For this reason we must use the cached ASTFile
        // information here instead of the potentially dangling pointer to the
        // ASTFile that is stored in the clang::Module object.
        //
        // Note: The implementation here assumes that all clang submodules
        //       belong to the same PCM file.
        ASTSourceDescriptor ParentDescriptor(*ClangModule->Parent);
        Parent = getOrCreateModule({ParentDescriptor.getModuleName(),
                                    ParentDescriptor.getPath(),
                                    Desc.getASTFile(), Desc.getSignature()},
                                   ClangModule->Parent);
      }
      return getOrCreateModule(ClangModule, Parent, Desc.getModuleName(),
                               Desc.getPath(), Signature, Desc.getASTFile());
    }
    // Handle PCH.
    return getOrCreateModule(Desc.getASTFile().bytes_begin(), nullptr,
                             Desc.getModuleName(), Desc.getPath(), Signature,
                             Desc.getASTFile());
  };

  static Optional<ASTSourceDescriptor> getClangModule(const ModuleDecl &M) {
    for (auto *FU : M.getFiles())
      if (auto *CMU = dyn_cast_or_null<ClangModuleUnit>(FU))
        if (auto Desc = CMU->getASTSourceDescriptor())
          return Desc;
    return None;
  }

  llvm::DIModule *getOrCreateModule(ImportedModule IM) {
    ModuleDecl *M = IM.importedModule;
    if (Optional<ASTSourceDescriptor> ModuleDesc = getClangModule(*M))
      return getOrCreateModule(*ModuleDesc, ModuleDesc->getModuleOrNull());
    StringRef Path = getFilenameFromDC(M);
    // Use the module 'real' name, which can be different from the name if module
    // aliasing was used (swift modules only). For example, if a source file has
    // 'import Foo', and '-module-alias Foo=Bar' was passed in, the real name of
    // the module on disk is Bar (.swiftmodule or .swiftinterface), and is used
    // for loading and mangling.
    StringRef Name = M->getRealName().str();
    return getOrCreateModule(M, TheCU, Name, Path);
  }

  TypeAliasDecl *getMetadataType(StringRef ArchetypeName) {
    TypeAliasDecl *&Entry = MetadataTypeDeclCache[ArchetypeName];
    if (Entry)
      return Entry;

    SourceLoc NoLoc;
    Entry = new (IGM.Context) TypeAliasDecl(
        NoLoc, NoLoc, IGM.Context.getIdentifier(ArchetypeName), NoLoc,
        /*genericparams*/ nullptr, IGM.Context.TheBuiltinModule);
    Entry->setUnderlyingType(IGM.Context.TheRawPointerType);
    return Entry;
  }

  /// Return the DIFile that is the ancestor of Scope.
  llvm::DIFile *getFile(llvm::DIScope *Scope) {
    while (!isa<llvm::DIFile>(Scope)) {
      switch (Scope->getTag()) {
      case llvm::dwarf::DW_TAG_lexical_block:
        Scope = cast<llvm::DILexicalBlock>(Scope)->getScope();
        break;
      case llvm::dwarf::DW_TAG_subprogram:
        Scope = cast<llvm::DISubprogram>(Scope)->getFile();
        break;
      default:
        return MainFile;
      }
      if (Scope)
        return MainFile;
    }
    return cast<llvm::DIFile>(Scope);
  }

  static Size getStorageSize(const llvm::DataLayout &DL,
                             ArrayRef<llvm::Value *> Storage) {
    unsigned size = 0;
    for (llvm::Value *Piece : Storage)
      size += DL.getTypeSizeInBits(Piece->getType());
    return Size(size);
  }

  StringRef getMangledName(DebugTypeInfo DbgTy) {
    if (DbgTy.isMetadataType())
      return MetadataTypeDeclCache.find(DbgTy.getDecl()->getName().str())
          ->getKey();

    // This is a bit of a hack. We need a generic signature to use for mangling.
    // If we started with an interface type, just use IGM.getCurGenericContext(),
    // since callers that use interface types typically push a signature that way.
    //
    // Otherwise, if we have a contextual type, find an archetype and ask it for
    // it's generic signature. The context generic signature from the IRGenModule
    // is unlikely to be useful here.
    GenericSignature Sig;
    Type Ty = DbgTy.getType();
    if (Ty->hasArchetype()) {
      Ty.findIf([&](Type t) -> bool {
        if (auto *archetypeTy = t->getAs<PrimaryArchetypeType>()) {
          Sig = archetypeTy->getGenericEnvironment()->getGenericSignature();
          return true;
        }

        if (auto *archetypeTy = t->getAs<SequenceArchetypeType>()) {
          Sig = archetypeTy->getGenericEnvironment()->getGenericSignature();
          return true;
        }

        return false;
      });

      Ty = Ty->mapTypeOutOfContext();
    } else {
      Sig = IGM.getCurGenericContext();
    }

    // Strip off top level of type sugar (except for type aliases).
    // We don't want Optional<T> and T? to get different debug types.
    while (true) {
      if (auto *ParenTy = dyn_cast<ParenType>(Ty.getPointer())) {
        Ty = ParenTy->getUnderlyingType();
        continue;
      }

      if (auto *SugarTy = dyn_cast<SyntaxSugarType>(Ty.getPointer())) {
        Ty = SugarTy->getSinglyDesugaredType();
        continue;
      }

      break;
    }

    // TODO: Eliminate substitutions in SILFunctionTypes for now.
    // On platforms where the substitutions affect representation, we will need
    // to preserve this info and teach type reconstruction about it.
    Ty = Ty->replaceSubstitutedSILFunctionTypesWithUnsubstituted(
        IGM.getSILModule());

    Mangle::ASTMangler Mangler;
    std::string Result = Mangler.mangleTypeForDebugger(Ty, Sig);

    // TODO(SR-15377): We currently cannot round trip some C++ types.
    if (!Opts.DisableRoundTripDebugTypes &&
        !Ty->getASTContext().LangOpts.EnableCXXInterop) {
      // Make sure we can reconstruct mangled types for the debugger.
#ifndef NDEBUG
      auto &Ctx = Ty->getASTContext();
      Type Reconstructed = Demangle::getTypeForMangling(Ctx, Result);
      if (!Reconstructed) {
        llvm::errs() << "Failed to reconstruct type for " << Result << "\n";
        llvm::errs() << "Original type:\n";
        Ty->dump(llvm::errs());
        abort();
      } else if (!Reconstructed->isEqual(Ty) &&
                 // FIXME: Some existential types are reconstructed without
                 // an explicit ExistentialType wrapping the constraint.
                 !equalWithoutExistentialTypes(Reconstructed, Ty) &&
                 !EqualUpToClangTypes().check(Reconstructed, Ty)) {
        // [FIXME: Include-Clang-type-in-mangling] Remove second check
        llvm::errs() << "Incorrect reconstructed type for " << Result << "\n";
        llvm::errs() << "Original type:\n";
        Ty->dump(llvm::errs());
        llvm::errs() << "Reconstructed type:\n";
        Reconstructed->dump(llvm::errs());
        abort();
      }
#endif
    }

    return BumpAllocatedString(Result);
  }

  llvm::DIDerivedType *createMemberType(CompletedDebugTypeInfo DbgTy,
                                        StringRef Name, unsigned &OffsetInBits,
                                        llvm::DIScope *Scope,
                                        llvm::DIFile *File,
                                        llvm::DINode::DIFlags Flags) {
    unsigned SizeOfByte = CI.getTargetInfo().getCharWidth();
    auto *Ty = getOrCreateType(DbgTy);
    auto *DITy = DBuilder.createMemberType(
        Scope, Name, File, 0,
        SizeOfByte * DbgTy.getSizeValue(), 0, OffsetInBits,
        Flags, Ty);
    OffsetInBits += getSizeInBits(Ty);
    OffsetInBits = llvm::alignTo(OffsetInBits,
                                 SizeOfByte * DbgTy.getAlignment().getValue());
    return DITy;
  }

  llvm::DICompositeType *
  createStructType(DebugTypeInfo DbgTy, NominalTypeDecl *Decl, Type BaseTy,
                   llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
                   unsigned SizeInBits, unsigned AlignInBits,
                   llvm::DINode::DIFlags Flags, llvm::DIType *DerivedFrom,
                   unsigned RuntimeLang, StringRef UniqueID) {
    StringRef Name = Decl->getName().str();

    // Forward declare this first because types may be recursive.
    auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
        llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
        llvm::dwarf::DW_LANG_Swift, SizeInBits, 0, Flags, UniqueID));

#ifndef NDEBUG
    if (UniqueID.empty())
      assert(!Name.empty() &&
             "no mangled name and no human readable name given");
    else
      assert((UniqueID.startswith("_T") ||
              UniqueID.startswith(MANGLING_PREFIX_STR)) &&
             "UID is not a mangled name");
#endif

    auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
    DITypeCache[DbgTy.getType()] = TH;
    // Collect the members.
    SmallVector<llvm::Metadata *, 16> Elements;
    unsigned OffsetInBits = 0;
    for (VarDecl *VD : Decl->getStoredProperties()) {
      auto memberTy = BaseTy->getTypeOfMember(IGM.getSwiftModule(), VD);

      if (auto DbgTy = CompletedDebugTypeInfo::getFromTypeInfo(
              VD->getInterfaceType(),
              IGM.getTypeInfoForUnlowered(
                  IGM.getSILTypes().getAbstractionPattern(VD), memberTy)))
        Elements.push_back(createMemberType(*DbgTy, VD->getName().str(),
                                            OffsetInBits, Scope, File, Flags));
      else
        // Without complete type info we can only create a forward decl.
        return DBuilder.createForwardDecl(
            llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
            llvm::dwarf::DW_LANG_Swift, SizeInBits, 0, UniqueID);
    }
    if (OffsetInBits > SizeInBits)
      SizeInBits = OffsetInBits;

    auto DITy = DBuilder.createStructType(
        Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
        DBuilder.getOrCreateArray(Elements), RuntimeLang, nullptr, UniqueID);
    DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
    return DITy;
  }

  llvm::DICompositeType *createEnumType(CompletedDebugTypeInfo DbgTy,
                                        EnumDecl *Decl, StringRef MangledName,
                                        llvm::DIScope *Scope,
                                        llvm::DIFile *File, unsigned Line,
                                        llvm::DINode::DIFlags Flags) {
    StringRef Name = Decl->getName().str();
    unsigned SizeOfByte = CI.getTargetInfo().getCharWidth();
    unsigned SizeInBits = DbgTy.getSizeValue() * SizeOfByte;
    // Default, since Swift doesn't allow specifying a custom alignment.
    unsigned AlignInBits = 0;

    // FIXME: Is DW_TAG_union_type the right thing here?
    // Consider using a DW_TAG_variant_type instead.
    auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
        llvm::dwarf::DW_TAG_union_type, MangledName, Scope, File, Line,
        llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
        MangledName));

    auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
    DITypeCache[DbgTy.getType()] = TH;

    SmallVector<llvm::Metadata *, 16> Elements;

    for (auto *ElemDecl : Decl->getAllElements()) {
      // FIXME <rdar://problem/14845818> Support enums.
      // Swift Enums can be both like DWARF enums and discriminated unions.
      // LLVM now supports variant types in debug metadata, which may be a
      // better fit.
      Optional<CompletedDebugTypeInfo> ElemDbgTy;
      if (Decl->hasRawType())
        // An enum with a raw type (enum E : Int {}), similar to a
        // DWARF enum.
        //
        // The storage occupied by the enum may be smaller than the
        // one of the raw type as long as it is large enough to hold
        // all enum values. Use the raw type for the debug type, but
        // the storage size from the enum.
        ElemDbgTy = CompletedDebugTypeInfo::get(
            DebugTypeInfo(Decl->getRawType(), DbgTy.getFragmentStorageType(),
                          DbgTy.getRawSize(), DbgTy.getAlignment(), true, false,
                          DbgTy.isSizeFragmentSize()));
      else if (auto ArgTy = ElemDecl->getArgumentInterfaceType()) {
        // A discriminated union. This should really be described as a
        // DW_TAG_variant_type. For now only describing the data.
        ArgTy = ElemDecl->getParentEnum()->mapTypeIntoContext(ArgTy);
        auto &TI = IGM.getTypeInfoForUnlowered(ArgTy);
        ElemDbgTy = CompletedDebugTypeInfo::getFromTypeInfo(ArgTy, TI);
      } else {
        // Discriminated union case without argument. Fallback to Int
        // as the element type; there is no storage here.
        Type IntTy = IGM.Context.getIntType();
        ElemDbgTy = CompletedDebugTypeInfo::get(
            DebugTypeInfo(IntTy, DbgTy.getFragmentStorageType(), Size(0),
                          Alignment(1), true, false, false));
      }
      if (!ElemDbgTy) {
        // Without complete type info we can only create a forward decl.
        return DBuilder.createForwardDecl(
            llvm::dwarf::DW_TAG_union_type, Name, Scope, File, Line,
            llvm::dwarf::DW_LANG_Swift, SizeInBits, 0, MangledName);
      }
      unsigned Offset = 0;
      auto MTy =
          createMemberType(*ElemDbgTy, ElemDecl->getBaseIdentifier().str(),
                           Offset, Scope, File, Flags);
      Elements.push_back(MTy);
    }
    auto DITy = DBuilder.createUnionType(
        Scope, Name, File, Line, SizeInBits, AlignInBits,
        Flags, DBuilder.getOrCreateArray(Elements),
        llvm::dwarf::DW_LANG_Swift, MangledName);

    DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
    return DITy;
  }

  llvm::DIType *getOrCreateDesugaredType(Type Ty, DebugTypeInfo DbgTy) {
    DebugTypeInfo BlandDbgTy(
        Ty, DbgTy.getFragmentStorageType(), DbgTy.getRawSize(),
        DbgTy.getAlignment(), DbgTy.hasDefaultAlignment(),
        DbgTy.isMetadataType(), DbgTy.isSizeFragmentSize());
    return getOrCreateType(BlandDbgTy);
  }

  uint64_t getSizeOfBasicType(CompletedDebugTypeInfo DbgTy) {
    uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
    uint64_t BitWidth = DbgTy.getSizeValue() * SizeOfByte;
    llvm::Type *StorageType = DbgTy.getFragmentStorageType()
                                  ? DbgTy.getFragmentStorageType()
                                  : IGM.DataLayout.getSmallestLegalIntType(
                                        IGM.getLLVMContext(), BitWidth);

    if (StorageType)
      return IGM.DataLayout.getTypeSizeInBits(StorageType);

    // This type is too large to fit in a register.
    assert(BitWidth > IGM.DataLayout.getLargestLegalIntTypeSizeInBits());
    return BitWidth;
  }

  /// Collect the type parameters of a bound generic type. This is needed to
  /// anchor any typedefs that may appear in parameters so they can be
  /// resolved in the debugger without needing to query the Swift module.
  llvm::DINodeArray collectGenericParams(BoundGenericType *BGT) {
    SmallVector<llvm::Metadata *, 16> TemplateParams;
    for (auto Param : BGT->getGenericArgs()) {
      TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
          TheCU, "", getOrCreateType(DebugTypeInfo::getForwardDecl(Param)),
          false));
    }
    return DBuilder.getOrCreateArray(TemplateParams);
  }

  /// Create a sized container for a sizeless type. Used to represent
  /// BoundGenericEnums that may have different sizes depending on what they are
  /// bound to, but still share a mangled name.
  llvm::DIType *createOpaqueStructWithSizedContainer(
      llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
      unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
      StringRef MangledName, llvm::DINodeArray BoundParams) {
    // This uses a separate cache and not DIRefMap for the inner type to avoid
    // associating the anonymous container (which is specific to the
    // variable/storage and not the type) with the MangledName.
    llvm::DICompositeType *UniqueType = nullptr;
    auto *UID = llvm::MDString::get(IGM.getLLVMContext(), MangledName);
    if (llvm::Metadata *V = InnerTypeCache.lookup(UID))
      UniqueType = cast<llvm::DICompositeType>(V);
    else {
      UniqueType = DBuilder.createForwardDecl(
          llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
          llvm::dwarf::DW_LANG_Swift, 0, 0, MangledName);
      if (BoundParams)
        DBuilder.replaceArrays(UniqueType, nullptr, BoundParams);
      InnerTypeCache[UID] = llvm::TrackingMDNodeRef(UniqueType);
    }

    llvm::Metadata *Elements[] = {DBuilder.createMemberType(
        Scope, "", File, 0, SizeInBits, AlignInBits, 0, Flags, UniqueType)};
    return DBuilder.createStructType(
        Scope, "", File, Line, SizeInBits, AlignInBits, Flags,
        /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
        llvm::dwarf::DW_LANG_Swift);
  }

  llvm::DIType *createPointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                         llvm::DIFile *File, unsigned Line,
                                         llvm::DINode::DIFlags Flags,
                                         StringRef MangledName) {
    if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
      auto FwdDecl = DBuilder.createForwardDecl(
          llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
          llvm::dwarf::DW_LANG_Swift, 0, 0);
      return createPointerSizedStruct(Scope, Name, FwdDecl, File, Line, Flags,
                                      MangledName);
    } else {
      unsigned SizeInBits = CI.getTargetInfo().getPointerWidth(0);
      return createOpaqueStruct(Scope, Name, File, Line, SizeInBits, 0, Flags,
                                MangledName);
    }
  }

  llvm::DIType *createPointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                         llvm::DIType *PointeeTy,
                                         llvm::DIFile *File, unsigned Line,
                                         llvm::DINode::DIFlags Flags,
                                         StringRef MangledName) {
    unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
    auto PtrTy = DBuilder.createPointerType(PointeeTy, PtrSize, 0);
    llvm::Metadata *Elements[] = {DBuilder.createMemberType(
        Scope, "ptr", File, 0, PtrSize, 0, 0, Flags, PtrTy)};
    return DBuilder.createStructType(
        Scope, Name, File, Line, PtrSize, 0, Flags,
        /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
        llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
  }

  llvm::DIType *
  createDoublePointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                 llvm::DIType *PointeeTy, llvm::DIFile *File,
                                 unsigned Line, llvm::DINode::DIFlags Flags,
                                 StringRef MangledName) {
    unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
    llvm::Metadata *Elements[] = {
        DBuilder.createMemberType(
            Scope, "ptr", File, 0, PtrSize, 0, 0, Flags,
            DBuilder.createPointerType(PointeeTy, PtrSize, 0)),
        DBuilder.createMemberType(
            Scope, "_", File, 0, PtrSize, 0, 0, Flags,
            DBuilder.createPointerType(nullptr, PtrSize, 0))};
    return DBuilder.createStructType(
        Scope, Name, File, Line, 2 * PtrSize, 0, Flags,
        /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
        llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
  }

  llvm::DIType *createFixedValueBufferStruct(llvm::DIType *PointeeTy) {
    unsigned Line = 0;
    unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
    llvm::DINode::DIFlags Flags = llvm::DINode::FlagArtificial;
    llvm::DIFile *File = MainFile;
    llvm::DIScope *Scope = TheCU;
    llvm::Metadata *Elements[] = {DBuilder.createMemberType(
        Scope, "contents", File, 0, PtrSize, 0, 0, Flags, PointeeTy)};
    return DBuilder.createStructType(
        Scope, "$swift.fixedbuffer", File, Line, 3 * PtrSize, 0, Flags,
        /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
        llvm::dwarf::DW_LANG_Swift, nullptr);
  }

  llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
                                      unsigned SizeInBits, unsigned AlignInBits,
                                      llvm::DINode::DIFlags Flags,
                                      StringRef MangledName) {
    auto FwdDecl = llvm::TempDINode(DBuilder.createReplaceableCompositeType(
        llvm::dwarf::DW_TAG_subroutine_type, MangledName, Scope, MainFile, 0,
        llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
        MangledName));

    auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
    DITypeCache[DbgTy.getType()] = TH;

    CanSILFunctionType FunTy;
    TypeBase *BaseTy = DbgTy.getType();
    if (auto *SILFnTy = dyn_cast<SILFunctionType>(BaseTy))
      FunTy = CanSILFunctionType(SILFnTy);
    // FIXME: Handling of generic parameters in SIL type lowering is in flux.
    // DebugInfo doesn't appear to care about the generic context, so just
    // throw it away before lowering.
    else if (isa<GenericFunctionType>(BaseTy)) {
      auto *fTy = cast<AnyFunctionType>(BaseTy);
      auto *nongenericTy = FunctionType::get(fTy->getParams(), fTy->getResult(),
                                             fTy->getExtInfo());

      FunTy = IGM.getLoweredType(nongenericTy).castTo<SILFunctionType>();
    } else
      FunTy = IGM.getLoweredType(BaseTy).castTo<SILFunctionType>();
    auto Params = createParameterTypes(FunTy);

    auto FnTy = DBuilder.createSubroutineType(Params, Flags);
    llvm::DIType *DITy;
    if (FunTy->getRepresentation() == SILFunctionType::Representation::Thick) {
      if (SizeInBits == 2 * CI.getTargetInfo().getPointerWidth(0))
        // This is a FunctionPairTy: { i8*, %swift.refcounted* }.
        DITy = createDoublePointerSizedStruct(Scope, MangledName, FnTy,
                                              MainFile, 0, Flags, MangledName);
      else
        // This is a generic function as noted above.
        DITy = createOpaqueStruct(Scope, MangledName, MainFile, 0, SizeInBits,
                                  AlignInBits, Flags, MangledName);
    } else {
      assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
      DITy = createPointerSizedStruct(Scope, MangledName, FnTy, MainFile, 0,
                                      Flags, MangledName);
    }
    DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
    return DITy;
  }

  llvm::DIType *createTuple(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
                            unsigned SizeInBits, unsigned AlignInBits,
                            llvm::DINode::DIFlags Flags,
                            StringRef MangledName) {
    TypeBase *BaseTy = DbgTy.getType();
    auto *TupleTy = BaseTy->castTo<TupleType>();

    SmallVector<llvm::Metadata *, 16> Elements;
    unsigned OffsetInBits = 0;
    auto genericSig = IGM.getCurGenericContext();
    for (auto ElemTy : TupleTy->getElementTypes()) {
      auto &elemTI = IGM.getTypeInfoForUnlowered(
          AbstractionPattern(genericSig, ElemTy->getCanonicalType()), ElemTy);
      if (auto DbgTy = CompletedDebugTypeInfo::getFromTypeInfo(ElemTy, elemTI))
        Elements.push_back(
            createMemberType(*DbgTy, "", OffsetInBits, Scope, MainFile, Flags));
      else
        // We can only create a forward declaration without complete size info.
        return DBuilder.createReplaceableCompositeType(
            llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, MainFile, 0,
            llvm::dwarf::DW_LANG_Swift, 0, AlignInBits, Flags, MangledName);
    }
    // FIXME: assert that SizeInBits == OffsetInBits.
    SizeInBits = OffsetInBits;
   
    auto FwdDecl = llvm::TempDINode(DBuilder.createReplaceableCompositeType(
        llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, MainFile, 0,
        llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
        MangledName));

    DITypeCache[DbgTy.getType()] = llvm::TrackingMDNodeRef(FwdDecl.get());

    auto DITy = DBuilder.createStructType(
        Scope, MangledName, MainFile, 0, SizeInBits, AlignInBits, Flags,
        nullptr, // DerivedFrom
        DBuilder.getOrCreateArray(Elements), llvm::dwarf::DW_LANG_Swift,
        nullptr, MangledName);

    DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
    return DITy;
  }

  llvm::DICompositeType *
  createOpaqueStruct(llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File,
                     unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
                     llvm::DINode::DIFlags Flags, StringRef MangledName) {
    return DBuilder.createStructType(
        Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
        /* DerivedFrom */ nullptr,
        DBuilder.getOrCreateArray(ArrayRef<llvm::Metadata *>()),
        llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
  }

  llvm::DIType *createType(DebugTypeInfo DbgTy, StringRef MangledName,
                           llvm::DIScope *Scope, llvm::DIFile *File) {
    // FIXME: For SizeInBits, clang uses the actual size of the type on
    // the target machine instead of the storage size that is alloca'd
    // in the LLVM IR. For all types that are boxed in a struct, we are
    // emitting the storage size of the struct, but it may be necessary
    // to emit the (target!) size of the underlying basic type.
    uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
    // FIXME: SizeInBits is redundant with DbgTy, remove it.
    uint64_t SizeInBits = 0;
    if (DbgTy.getTypeSize())
      SizeInBits = DbgTy.getTypeSize()->getValue() * SizeOfByte;
    unsigned AlignInBits = DbgTy.hasDefaultAlignment()
                               ? 0
                               : DbgTy.getAlignment().getValue() * SizeOfByte;
    unsigned Encoding = 0;
    llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

    TypeBase *BaseTy = DbgTy.getType();

    if (!BaseTy) {
      LLVM_DEBUG(llvm::dbgs() << "Type without TypeBase: ";
                 DbgTy.getType()->dump(llvm::dbgs()); llvm::dbgs() << "\n");
      if (!InternalType) {
        StringRef Name = "<internal>";
        InternalType = DBuilder.createForwardDecl(
            llvm::dwarf::DW_TAG_structure_type, Name, Scope, File,
            /*Line*/ 0, llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits,
            MangledName);
      }
      return InternalType;
    }

    // Here goes!
    switch (BaseTy->getKind()) {
    case TypeKind::BuiltinInteger: {
      Encoding = llvm::dwarf::DW_ATE_unsigned;
      if (auto CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy))
        SizeInBits = getSizeOfBasicType(*CompletedDbgTy);
      break;
    }

    case TypeKind::BuiltinIntegerLiteral: {
      Encoding = llvm::dwarf::DW_ATE_unsigned; // ?
      if (auto CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy))
        SizeInBits = getSizeOfBasicType(*CompletedDbgTy);
      break;
    }

    case TypeKind::BuiltinFloat: {
      auto *FloatTy = BaseTy->castTo<BuiltinFloatType>();
      // Assuming that the bitwidth and FloatTy->getFPKind() are identical.
      SizeInBits = FloatTy->getBitWidth();
      Encoding = llvm::dwarf::DW_ATE_float;
      break;
    }

    case TypeKind::BuiltinNativeObject: {
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      auto PTy =
          DBuilder.createPointerType(nullptr, PtrSize, 0,
                                     /* DWARFAddressSpace */ None, MangledName);
      return DBuilder.createObjectPointerType(PTy);
    }

    case TypeKind::BuiltinBridgeObject: {
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      auto PTy =
          DBuilder.createPointerType(nullptr, PtrSize, 0,
                                     /* DWARFAddressSpace */ None, MangledName);
      return DBuilder.createObjectPointerType(PTy);
    }

    case TypeKind::BuiltinRawPointer: {
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      return DBuilder.createPointerType(nullptr, PtrSize, 0,
                                        /* DWARFAddressSpace */ None,
                                        MangledName);
    }

    case TypeKind::BuiltinRawUnsafeContinuation: {
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      return DBuilder.createPointerType(nullptr, PtrSize, 0,
                                        /* DWARFAddressSpace */ None,
                                        MangledName);
    }

    case TypeKind::BuiltinJob: {
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      return DBuilder.createPointerType(nullptr, PtrSize, 0,
                                        /* DWARFAddressSpace */ None,
                                        MangledName);
    }

    case TypeKind::BuiltinExecutor: {
      return createDoublePointerSizedStruct(
          Scope, "Builtin.Executor", nullptr, MainFile, 0,
          llvm::DINode::FlagArtificial, MangledName);
    }

    case TypeKind::DynamicSelf: {
      // Self. We don't have a way to represent instancetype in DWARF,
      // so we emit the static type instead. This is similar to what we
      // do with instancetype in Objective-C.
      auto *DynamicSelfTy = BaseTy->castTo<DynamicSelfType>();
      auto SelfTy =
          getOrCreateDesugaredType(DynamicSelfTy->getSelfType(), DbgTy);
      return DBuilder.createTypedef(SelfTy, MangledName, File, 0, File);
    }

    // Even builtin swift types usually come boxed in a struct.
    case TypeKind::Struct: {
      auto *StructTy = BaseTy->castTo<StructType>();
      auto *Decl = StructTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      // No line numbers are attached to type forward declarations.  This is
      // intentional: It interfers with the efficacy of incremental builds. We
      // don't want a whitespace change to an secondary file trigger a
      // recompilation of the debug info of a primary source file.
      unsigned FwdDeclLine = 0;
      if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
        return createStructType(DbgTy, Decl, StructTy, Scope, File, L.line,
                                SizeInBits, AlignInBits, Flags, nullptr,
                                llvm::dwarf::DW_LANG_Swift, MangledName);
      StringRef Name = Decl->getName().str();
      if (DbgTy.getTypeSize())
        return createOpaqueStruct(Scope, Name, File, FwdDeclLine, SizeInBits,
                                  AlignInBits, Flags, MangledName);
      return DBuilder.createForwardDecl(
          llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, FwdDeclLine,
          llvm::dwarf::DW_LANG_Swift, 0, AlignInBits, MangledName);
    }

    case TypeKind::Class: {
      // Classes are represented as DW_TAG_structure_type. This way the
      // DW_AT_APPLE_runtime_class(DW_LANG_Swift) attribute can be
      // used to differentiate them from C++ and ObjC classes.
      auto *ClassTy = BaseTy->castTo<ClassType>();
      auto *Decl = ClassTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;
      assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
      return createPointerSizedStruct(Scope, Decl->getNameStr(), File,
                                      FwdDeclLine, Flags, MangledName);
    }

    case TypeKind::Protocol: {
      auto *ProtocolTy = BaseTy->castTo<ProtocolType>();
      auto *Decl = ProtocolTy->getDecl();
      // FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;
      return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
                                File, FwdDeclLine, SizeInBits, AlignInBits,
                                Flags, MangledName);
    }

    case TypeKind::Existential:
    case TypeKind::ProtocolComposition: {
      auto *Decl = DbgTy.getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;
      return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
                                File, FwdDeclLine, SizeInBits, AlignInBits,
                                Flags, MangledName);
    }

    case TypeKind::UnboundGeneric: {
      auto *UnboundTy = BaseTy->castTo<UnboundGenericType>();
      auto *Decl = UnboundTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;
      assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
      return createPointerSizedStruct(Scope,
                                      Decl ? Decl->getNameStr() : MangledName,
                                      File, FwdDeclLine, Flags, MangledName);
    }

    case TypeKind::BoundGenericStruct: {
      auto *StructTy = BaseTy->castTo<BoundGenericStructType>();
      auto *Decl = StructTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;
      return createOpaqueStructWithSizedContainer(
          Scope, Decl ? Decl->getNameStr() : "", File, FwdDeclLine, SizeInBits,
          AlignInBits, Flags, MangledName, collectGenericParams(StructTy));
    }

    case TypeKind::BoundGenericClass: {
      auto *ClassTy = BaseTy->castTo<BoundGenericClassType>();
      auto *Decl = ClassTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;

      // TODO: We may want to peek at Decl->isObjC() and set this
      // attribute accordingly.
      assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
      return createPointerSizedStruct(Scope,
                                      Decl ? Decl->getNameStr() : MangledName,
                                      File, FwdDeclLine, Flags, MangledName);
    }

    case TypeKind::Tuple: {
      // Tuples are also represented as structs.  Since tuples are ephemeral
      // (not nominal) they don't have a source location.
      if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
        return createTuple(DbgTy, Scope, SizeInBits, AlignInBits, Flags,
                           MangledName);
      else
        return createOpaqueStruct(Scope, MangledName, MainFile, 0, SizeInBits,
                                  AlignInBits, Flags, MangledName);
    }

    case TypeKind::InOut:
      break;

    case TypeKind::OpaqueTypeArchetype:
    case TypeKind::PrimaryArchetype:
    case TypeKind::OpenedArchetype:
    case TypeKind::NestedArchetype:
    case TypeKind::SequenceArchetype: {
      auto *Archetype = BaseTy->castTo<ArchetypeType>();
      AssociatedTypeDecl *assocType = nullptr;
      if (auto nested = dyn_cast<NestedArchetypeType>(Archetype))
        assocType = nested->getAssocType();
      auto L = getFilenameAndLocation(*this, assocType);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;
      auto Superclass = Archetype->getSuperclass();
      auto DerivedFrom = Superclass.isNull()
                             ? nullptr
                             : getOrCreateDesugaredType(Superclass, DbgTy);
      auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
          llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File,
          FwdDeclLine, llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits,
          Flags, MangledName));

      // Emit the protocols the archetypes conform to.
      SmallVector<llvm::Metadata *, 4> Protocols;
      for (auto *ProtocolDecl : Archetype->getConformsTo()) {
        auto PTy =
            IGM.getLoweredType(ProtocolDecl->getInterfaceType()).getASTType();
        auto PDbgTy = DebugTypeInfo::getFromTypeInfo(
            ProtocolDecl->getInterfaceType(), IGM.getTypeInfoForLowered(PTy),
            false);
        auto PDITy = getOrCreateType(PDbgTy);
        Protocols.push_back(
            DBuilder.createInheritance(FwdDecl.get(), PDITy, 0, 0, Flags));
      }
      auto DITy = DBuilder.createStructType(
          Scope, MangledName, File, FwdDeclLine, SizeInBits, AlignInBits, Flags,
          DerivedFrom, DBuilder.getOrCreateArray(Protocols),
          llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);

      DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
      return DITy;
    }

    case TypeKind::ExistentialMetatype:
    case TypeKind::Metatype: {
      // Metatypes are (mostly) singleton type descriptors, often without
      // storage.
      Flags |= llvm::DINode::FlagArtificial;
      auto L = getFilenameAndLocation(*this, DbgTy.getDecl());
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;

      return DBuilder.createStructType(
          Scope, MangledName, File, FwdDeclLine, SizeInBits, AlignInBits, Flags,
          nullptr, nullptr, llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
    }

    case TypeKind::SILFunction:
    case TypeKind::Function:
    case TypeKind::GenericFunction: {
      if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
        return createFunctionPointer(DbgTy, Scope, SizeInBits, AlignInBits,
                                     Flags, MangledName);
      else
        return createOpaqueStruct(Scope, MangledName, MainFile, 0, SizeInBits,
                                  AlignInBits, Flags, MangledName);
    }

    case TypeKind::Enum: {
      auto *EnumTy = BaseTy->castTo<EnumType>();
      auto *Decl = EnumTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;
      if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
        if (auto CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy))
          return createEnumType(*CompletedDbgTy, Decl, MangledName, Scope, File,
                                L.line, Flags);
      return createOpaqueStruct(Scope, Decl->getName().str(), File, FwdDeclLine,
                                SizeInBits, AlignInBits, Flags, MangledName);
    }

    case TypeKind::BoundGenericEnum: {
      auto *EnumTy = BaseTy->castTo<BoundGenericEnumType>();
      auto *Decl = EnumTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto *File = getOrCreateFile(L.filename);
      unsigned FwdDeclLine = 0;

      return createOpaqueStructWithSizedContainer(
          Scope, Decl->getName().str(), File, FwdDeclLine, SizeInBits,
          AlignInBits, Flags, MangledName, collectGenericParams(EnumTy));
    }

    case TypeKind::BuiltinVector: {
      // FIXME: Emit the name somewhere.
      (void)MangledName;
      auto *BuiltinVectorTy = BaseTy->castTo<BuiltinVectorType>();
      auto ElemTy = BuiltinVectorTy->getElementType();
      auto ElemDbgTy = DebugTypeInfo::getFromTypeInfo(
          ElemTy, IGM.getTypeInfoForUnlowered(ElemTy), false);
      unsigned Count = BuiltinVectorTy->getNumElements();
      auto Subscript = DBuilder.getOrCreateSubrange(0, Count ? Count : -1);
      return DBuilder.createVectorType(SizeInBits, AlignInBits,
                                       getOrCreateType(ElemDbgTy),
                                       DBuilder.getOrCreateArray(Subscript));
    }

    // Reference storage types.
#define REF_STORAGE(Name, ...) case TypeKind::Name##Storage:
#include "swift/AST/ReferenceStorage.def"
      {
        auto *ReferenceTy = cast<ReferenceStorageType>(BaseTy);
        auto CanTy = ReferenceTy->getReferentType();
        auto L = getFilenameAndLocation(*this, DbgTy.getDecl());
        auto *File = getOrCreateFile(L.filename);
        unsigned CompilerGeneratedLine = 0;

        return DBuilder.createTypedef(getOrCreateDesugaredType(CanTy, DbgTy),
                                      MangledName, File, CompilerGeneratedLine,
                                      File);
      }

      // Sugared types.

    case TypeKind::TypeAlias: {
      auto *TypeAliasTy = cast<TypeAliasType>(BaseTy);
      auto *Decl = TypeAliasTy->getDecl();
      auto L = getFilenameAndLocation(*this, Decl);
      auto AliasedTy = TypeAliasTy->getSinglyDesugaredType();
      auto *File = getOrCreateFile(L.filename);

      // For TypeAlias types, the DeclContext for the aliased type is
      // in the decl of the alias type.
      DebugTypeInfo AliasedDbgTy(AliasedTy, DbgTy.getFragmentStorageType(),
                                 DbgTy.getRawSize(), DbgTy.getAlignment(),
                                 DbgTy.hasDefaultAlignment(), false,
                                 DbgTy.isSizeFragmentSize());
      return DBuilder.createTypedef(getOrCreateType(AliasedDbgTy), MangledName,
                                    File, 0, Scope);
    }

    case TypeKind::Paren: {
      auto Ty = cast<ParenType>(BaseTy)->getUnderlyingType();
      return getOrCreateDesugaredType(Ty, DbgTy);
    }

    // SyntaxSugarType derivations.
    case TypeKind::Dictionary:
    case TypeKind::ArraySlice:
    case TypeKind::Optional:
    case TypeKind::VariadicSequence: {
      auto *SyntaxSugarTy = cast<SyntaxSugarType>(BaseTy);
      auto *CanTy = SyntaxSugarTy->getSinglyDesugaredType();
      return getOrCreateDesugaredType(CanTy, DbgTy);
    }

    // SILBox should appear only inside of coroutine contexts.
    case TypeKind::SILBox:
    case TypeKind::DependentMember:
    case TypeKind::GenericTypeParam: {
      // FIXME: Provide a more meaningful debug type.
      return DBuilder.createStructType(
          Scope, MangledName, File, 0, SizeInBits, AlignInBits, Flags, nullptr,
          nullptr, llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
    }

    // The following types exist primarily for internal use by the type
    // checker.
    case TypeKind::Error:
    case TypeKind::Unresolved:
    case TypeKind::LValue:
    case TypeKind::TypeVariable:
    case TypeKind::Placeholder:
    case TypeKind::Module:
    case TypeKind::SILBlockStorage:
    case TypeKind::SILToken:
    case TypeKind::BuiltinUnsafeValueBuffer:
    case TypeKind::BuiltinDefaultActorStorage:

      LLVM_DEBUG(llvm::dbgs() << "Unhandled type: ";
                 DbgTy.getType()->dump(llvm::dbgs()); llvm::dbgs() << "\n");
      MangledName = "<unknown>";
    }
    return DBuilder.createBasicType(MangledName, SizeInBits, Encoding);
  }

  /// Determine if there exists a name mangling for the given type.
  static bool canMangle(TypeBase *Ty) {
    // TODO: C++ types are not yet supported (SR-13223).
    if (Ty->getStructOrBoundGenericStruct() &&
        isa_and_nonnull<clang::CXXRecordDecl>(
            Ty->getStructOrBoundGenericStruct()->getClangDecl()))
      return false;

    switch (Ty->getKind()) {
    case TypeKind::GenericFunction: // Not yet supported.
    case TypeKind::SILBlockStorage: // Not supported at all.
      return false;
    default:
      return true;
    }
  }

  llvm::DIType *getTypeOrNull(TypeBase *Ty) {
    auto CachedType = DITypeCache.find(Ty);
    if (CachedType != DITypeCache.end()) {
      // Verify that the information still exists.
      if (llvm::Metadata *Val = CachedType->second) {
        auto DITy = cast<llvm::DIType>(Val);
        return DITy;
      }
    }
    return nullptr;
  }

  /// The private discriminator is represented as an inline namespace.
  llvm::DIScope *getFilePrivateScope(llvm::DIScope *Parent, TypeDecl *Decl) {
    // Retrieve the private discriminator.
    auto *MSC = Decl->getDeclContext()->getModuleScopeContext();
    auto *FU = cast<FileUnit>(MSC);
    Identifier PD = FU->getDiscriminatorForPrivateValue(Decl);
    bool ExportSymbols = true;
    return DBuilder.createNameSpace(Parent, PD.str(), ExportSymbols);
  }

  llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) {
    // Is this an empty type?
    if (DbgTy.isNull())
      // We can't use the empty type as an index into DenseMap.
      return createType(DbgTy, "", TheCU, MainFile);

    // Look in the cache first.
    if (auto *DITy = getTypeOrNull(DbgTy.getType()))
      return DITy;

    // Second line of defense: Look up the mangled name. TypeBase*'s are
    // not necessarily unique, but name mangling is too expensive to do
    // every time.
    StringRef MangledName;
    llvm::MDString *UID = nullptr;
    if (canMangle(DbgTy.getType())) {
      MangledName = getMangledName(DbgTy);
      UID = llvm::MDString::get(IGM.getLLVMContext(), MangledName);
      if (llvm::Metadata *CachedTy = DIRefMap.lookup(UID)) {
        auto DITy = cast<llvm::DIType>(CachedTy);
        return DITy;
      }
    }

    // Retrieve the context of the type, as opposed to the DeclContext
    // of the variable.
    //
    // FIXME: Builtin and qualified types in LLVM have no parent
    // scope. TODO: This can be fixed by extending DIBuilder.
    llvm::DIScope *Scope = nullptr;
    // Make sure to retrieve the context of the type alias, not the pointee.
    DeclContext *Context = nullptr;
    const Decl *TypeDecl = nullptr;
    const clang::Decl *ClangDecl = nullptr;
    if (auto Alias = dyn_cast<TypeAliasType>(DbgTy.getType())) {
      TypeAliasDecl *AliasDecl = Alias->getDecl();
      TypeDecl = AliasDecl;
      Context = AliasDecl->getParent();
      ClangDecl = AliasDecl->getClangDecl();
    } else if (auto *ND = DbgTy.getType()->getNominalOrBoundGenericNominal()) {
      TypeDecl = ND;
      Context = ND->getParent();
      ClangDecl = ND->getClangDecl();
    }
    if (ClangDecl) {
      clang::ASTReader &Reader = *CI.getClangInstance().getASTReader();
      auto Idx = ClangDecl->getOwningModuleID();
      auto SubModuleDesc = Reader.getSourceDescriptor(Idx);
      auto TopLevelModuleDesc = getClangModule(*TypeDecl->getModuleContext());
      if (SubModuleDesc) {
        if (TopLevelModuleDesc)
          // Describe the submodule, but substitute the cached ASTFile from
          // the toplevel module. The ASTFile pointer in SubModule may be
          // dangling and cant be trusted.
          Scope = getOrCreateModule({SubModuleDesc->getModuleName(),
                                     SubModuleDesc->getPath(),
                                     TopLevelModuleDesc->getASTFile(),
                                     TopLevelModuleDesc->getSignature()},
                                    SubModuleDesc->getModuleOrNull());
        else if (SubModuleDesc->getModuleOrNull() == nullptr)
          // This is (bridging header) PCH.
          Scope = getOrCreateModule(*SubModuleDesc, nullptr);
      }
    }
    if (!Scope)
      Scope = getOrCreateContext(Context);

    // Scope outermost fileprivate decls in an inline private discriminator
    // namespace.
    if (auto *Decl = DbgTy.getDecl())
      if (Decl->isOutermostPrivateOrFilePrivateScope())
        Scope = getFilePrivateScope(Scope, Decl);

    // If this is a forward decl, create one for this mangled name and don't
    // cache it.
    if (DbgTy.isForwardDecl() && !isa<TypeAliasType>(DbgTy.getType())) {
      auto *FwdDecl = DBuilder.createReplaceableCompositeType(
          llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, 0, 0,
          llvm::dwarf::DW_LANG_Swift, 0, 0, llvm::DINode::FlagFwdDecl,
          MangledName);
      ReplaceMap.emplace_back(
          std::piecewise_construct, std::make_tuple(DbgTy.getType()),
          std::make_tuple(static_cast<llvm::Metadata *>(FwdDecl)));
      return FwdDecl;
    }
    llvm::DIType *DITy = createType(DbgTy, MangledName, Scope, getFile(Scope));

    // Don't cache a type alias to a forward declaration either.
    if (DbgTy.isForwardDecl())
      return DITy;

    // Incrementally build the DIRefMap.
    if (auto *CTy = dyn_cast<llvm::DICompositeType>(DITy)) {
#ifndef NDEBUG
      // Sanity check.
      if (llvm::Metadata *V = DIRefMap.lookup(UID)) {
        auto *CachedTy = cast<llvm::DIType>(V);
        assert(CachedTy == DITy && "conflicting types for one UID");
      }
#endif
      // If this type supports a UID, enter it to the cache.
      if (auto UID = CTy->getRawIdentifier()) {
        assert(UID->getString() == MangledName &&
               "Unique identifier is different from mangled name ");
        DIRefMap[UID] = llvm::TrackingMDNodeRef(DITy);
      }
    }

    // Store it in the cache.
    DITypeCache.insert({DbgTy.getType(), llvm::TrackingMDNodeRef(DITy)});

    return DITy;
  }
};

IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts,
                                       ClangImporter &CI, IRGenModule &IGM,
                                       llvm::Module &M,
                                       StringRef MainOutputFilenameForDebugInfo,
                                       StringRef PD)
    : Opts(Opts), CI(CI), SM(IGM.Context.SourceMgr), M(M), DBuilder(M),
      IGM(IGM), DebugPrefixMap(Opts.DebugPrefixMap) {
  assert(Opts.DebugInfoLevel > IRGenDebugInfoLevel::None &&
         "no debug info should be generated");
  llvm::SmallString<256> SourcePath;
  if (MainOutputFilenameForDebugInfo.empty())
    SourcePath = "<unknown>";
  else
    SourcePath = MainOutputFilenameForDebugInfo;

  unsigned Lang = llvm::dwarf::DW_LANG_Swift;
  std::string Producer = version::getSwiftFullVersion(
      IGM.Context.LangOpts.EffectiveLanguageVersion);
  unsigned Major, Minor;
  std::tie(Major, Minor) = version::getSwiftNumericVersion();
  unsigned MajorRuntimeVersion = Major;

  // No split DWARF on Darwin.
  StringRef SplitName = StringRef();
  // Note that File + Dir need not result in a valid path.
  // The directory part of the main file is the current working directory.
  std::string RemappedFile = DebugPrefixMap.remapPath(SourcePath);
  std::string RemappedDir = DebugPrefixMap.remapPath(Opts.DebugCompilationDir);
  bool RelFile = llvm::sys::path::is_relative(RemappedFile);
  bool RelDir = llvm::sys::path::is_relative(RemappedDir);
  MainFile = (RelFile && RelDir)
                 ? createFile(SourcePath, {}, {})
                 : DBuilder.createFile(RemappedFile, RemappedDir);

  StringRef Sysroot = IGM.Context.SearchPathOpts.SDKPath;
  StringRef SDK;
  {
    auto B = llvm::sys::path::rbegin(Sysroot);
    auto E = llvm::sys::path::rend(Sysroot);
    auto It = std::find_if(B, E, [](auto SDK) { return SDK.endswith(".sdk"); });
    if (It != E)
      SDK = *It;
  }

  TheCU = DBuilder.createCompileUnit(
      Lang, MainFile, Producer, Opts.shouldOptimize(), Opts.getDebugFlags(PD),
      MajorRuntimeVersion, SplitName,
      Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables
          ? llvm::DICompileUnit::FullDebug
          : llvm::DICompileUnit::LineTablesOnly,
      /* DWOId */ 0, /* SplitDebugInlining */ true,
      /* DebugInfoForProfiling */ false,
      llvm::DICompileUnit::DebugNameTableKind::Default,
      /* RangesBaseAddress */ false, DebugPrefixMap.remapPath(Sysroot), SDK);

  // Because the swift compiler relies on Clang to setup the Module,
  // the clang CU is always created first.  Several dwarf-reading
  // tools (older versions of ld64, and lldb) can get confused if the
  // first CU in an object is empty, so ensure that the Swift CU comes
  // first by rearranging the list of CUs in the LLVM module.
  llvm::NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
  SmallVector<llvm::DICompileUnit *, 2> CUs;
  for (auto *N : CU_Nodes->operands())
    CUs.push_back(cast<llvm::DICompileUnit>(N));
  CU_Nodes->dropAllReferences();
  for (auto CU = CUs.rbegin(), CE = CUs.rend(); CU != CE; ++CU)
    CU_Nodes->addOperand(*CU);

  // Create a module for the current compile unit.
  auto *MDecl = IGM.getSwiftModule();
  llvm::sys::path::remove_filename(SourcePath);
  MainModule = getOrCreateModule(MDecl, TheCU, Opts.ModuleName, SourcePath);
  DBuilder.createImportedModule(MainFile, MainModule, MainFile, 0);

  // Macro definitions that were defined by the user with "-Xcc -D" on the
  // command line. This does not include any macros defined by ClangImporter.
  llvm::raw_svector_ostream OS(ConfigMacros);
  unsigned I = 0;
  // Translate the macro definitions back into a commmand line.
  for (auto &Macro : Opts.ClangDefines) {
    if (++I > 1)
      OS << ' ';
    OS << '"';
    for (char c : Macro)
      switch (c) {
      case '\\':
        OS << "\\\\";
        break;
      case '"':
        OS << "\\\"";
        break;
      default:
        OS << c;
      }
    OS << '"';
  }
}

void IRGenDebugInfoImpl::finalize() {
  assert(LocationStack.empty() && "Mismatch of pushLoc() and popLoc().");

  // Get the list of imported modules (which may actually be different
  // from all ImportDecls).
  SmallVector<ImportedModule, 8> ModuleWideImports;
  IGM.getSwiftModule()->getImportedModules(
      ModuleWideImports, {ModuleDecl::ImportFilterKind::Exported,
                          ModuleDecl::ImportFilterKind::Default,
                          ModuleDecl::ImportFilterKind::ImplementationOnly});
  for (auto M : ModuleWideImports)
    if (!ImportedModules.count(M.importedModule))
      createImportedModule(MainFile, M, MainFile, 0);

  // Finalize all replaceable forward declarations.
  for (auto &Ty : ReplaceMap) {
    llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(Ty.second));
    llvm::Metadata *Replacement;
    if (auto *FullType = getTypeOrNull(Ty.first))
      Replacement = FullType;
    else
      Replacement = Ty.second;
    DBuilder.replaceTemporary(std::move(FwdDecl),
                              cast<llvm::MDNode>(Replacement));
  }
  // Finalize the DIBuilder.
  DBuilder.finalize();
}

#ifndef NDEBUG
bool IRGenDebugInfoImpl::lineEntryIsSane(SILLocation::FilenameAndLocation DL,
                                         const SILDebugScope *DS) {
  // All bets are off for optimized code.
  if (!VerifyLineTable || Opts.shouldOptimize())
    return true;
  // We entered a new lexical block.
  if (DS != LastScope)
    PreviousLineEntries.clear();
  if (DL.line == 0 || DL == PreviousFilenameAndLocation)
    return true;
  // Save the last non-zero line entry.
  PreviousFilenameAndLocation = DL;
  auto ItNew = PreviousLineEntries.insert(FilenameAndLocationKey(DL));
  // Return true iff DL was not yet in PreviousLineEntries.
  return ItNew.second;
}
#endif

void IRGenDebugInfoImpl::setCurrentLoc(IRBuilder &Builder,
                                       const SILDebugScope *DS,
                                       SILLocation Loc) {
  assert(DS && "empty scope");
  auto *Scope = getOrCreateScope(DS);
  if (!Scope)
    return;

  // NOTE: In CodeView, zero is not an artificial line location. We try to
  //       avoid those line locations near user code to reduce the number
  //       of breaks in the linetables.
  SILLocation::FilenameAndLocation L;
  SILFunction *Fn = DS->getInlinedFunction();
  if (Fn && (Fn->isThunk() || Fn->isTransparent())) {
    L = *SILLocation::getCompilerGeneratedLoc();
  } else if (DS == LastScope && Loc.isAutoGenerated()) {
    // Reuse the last source location if we are still in the same
    // scope to get a more contiguous line table.
    L = LastFilenameAndLocation;
  } else if (DS == LastScope &&
             (Loc.is<ArtificialUnreachableLocation>() || Loc.isLineZero(SM)) &&
             Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView) {
    // If the scope has not changed and the line number is either zero or
    // artificial, we want to keep the most recent debug location.
    L = LastFilenameAndLocation;
  } else {
    // Decode the location.
    if (!Loc.isInPrologue() ||
        Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView)
      L = decodeFilenameAndLocation(Loc);

    // Otherwise use a line 0 artificial location, but the file from the
    // location. If we are emitting CodeView, we do not want to use line zero
    // since it does not represent an artificial line location.
    if (Loc.isAutoGenerated() &&
        Opts.DebugInfoFormat != IRGenDebugInfoFormat::CodeView) {
      L.line = 0;
      L.column = 0;
    }
  }

  auto *File = getOrCreateFile(L.filename);
  if (File->getFilename() != Scope->getFilename()) {
    // We changed files in the middle of a scope. This happens, for
    // example, when constructors are inlined. Create a new scope to
    // reflect this.
    auto File = getOrCreateFile(L.filename);
    Scope = DBuilder.createLexicalBlockFile(Scope, File);
  }

  // FIXME: Enable this assertion.
  assert(lineEntryIsSane(L, DS) &&
         "non-contiguous debug location in same scope at -Onone");
  LastFilenameAndLocation = L;
  LastScope = DS;

  auto *InlinedAt = createInlinedAt(DS);
  assert(((!InlinedAt) || (InlinedAt && Scope)) && "inlined w/o scope");
  assert(parentScopesAreSane(DS) && "parent scope sanity check failed");
  auto DL = llvm::DILocation::get(IGM.getLLVMContext(), L.line, L.column, Scope,
                                  InlinedAt);
  Builder.SetCurrentDebugLocation(DL);
}

void IRGenDebugInfoImpl::addFailureMessageToCurrentLoc(IRBuilder &Builder,
                                                       StringRef failureMsg) {
  auto TrapLoc = Builder.getCurrentDebugLocation();

  // Create a function in the debug info which has failureMsg as name.
  // TrapSc is the SIL debug scope which corresponds to TrapSP in the LLVM debug
  // info.
  RegularLocation ALoc = RegularLocation::getAutoGeneratedLocation();
  const SILDebugScope *TrapSc = new (IGM.getSILModule()) SILDebugScope(ALoc);

  llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(nullptr);

  std::string FuncName = "Swift runtime failure: ";
  FuncName += failureMsg;

  llvm::DISubprogram *TrapSP = DBuilder.createFunction(
      MainModule, FuncName, StringRef(), TrapLoc->getFile(), 0, DIFnTy, 0,
      llvm::DINode::FlagArtificial, llvm::DISubprogram::SPFlagDefinition,
      nullptr, nullptr, nullptr);

  ScopeCache[TrapSc] = llvm::TrackingMDNodeRef(TrapSP);
  LastScope = TrapSc;

  assert(parentScopesAreSane(TrapSc) && "parent scope sanity check failed");

  // Wrap the existing TrapLoc into the failure function.
  auto DL = llvm::DILocation::get(IGM.getLLVMContext(), 0, 0, TrapSP, TrapLoc);
  Builder.SetCurrentDebugLocation(DL);
}

void IRGenDebugInfoImpl::clearLoc(IRBuilder &Builder) {
  LastFilenameAndLocation = {};
  LastScope = nullptr;
  Builder.SetCurrentDebugLocation(llvm::DebugLoc());
}

/// Push the current debug location onto a stack and initialize the
/// IRBuilder to an empty location.
void IRGenDebugInfoImpl::pushLoc() {
  LocationStack.push_back(std::make_pair(LastFilenameAndLocation, LastScope));
  LastFilenameAndLocation = {};
  LastScope = nullptr;
}

/// Restore the current debug location from the stack.
void IRGenDebugInfoImpl::popLoc() {
  std::tie(LastFilenameAndLocation, LastScope) = LocationStack.pop_back_val();
}

/// This is done for WinDbg to avoid having two non-contiguous sets of
/// instructions because the ``@llvm.trap`` instruction gets placed at the end
/// of the function.
void IRGenDebugInfoImpl::setInlinedTrapLocation(IRBuilder &Builder,
                                                const SILDebugScope *Scope) {
  if (Opts.DebugInfoFormat != IRGenDebugInfoFormat::CodeView)
    return;

  // The @llvm.trap could be inlined into a chunk of code that was also inlined.
  // If this is the case then simply using the LastScope's location would
  // generate debug info that claimed Function A owned Block X and Block X
  // thought it was owned by Function B. Therefore, we need to find the last
  // inlined scope to point to.
  const SILDebugScope *TheLastScope = LastScope;
  while (TheLastScope->InlinedCallSite &&
         TheLastScope->InlinedCallSite != TheLastScope) {
    TheLastScope = TheLastScope->InlinedCallSite;
  }
  auto LastLocation = llvm::DILocation::get(
      IGM.getLLVMContext(), LastFilenameAndLocation.line,
      LastFilenameAndLocation.column, getOrCreateScope(TheLastScope));
  // FIXME: This location should point to stdlib instead of being artificial.
  auto DL = llvm::DILocation::get(IGM.getLLVMContext(), 0, 0,
                                  getOrCreateScope(Scope), LastLocation);
  Builder.SetCurrentDebugLocation(DL);
}

void IRGenDebugInfoImpl::setEntryPointLoc(IRBuilder &Builder) {
  auto DL = llvm::DILocation::get(IGM.getLLVMContext(), 0, 0, getEntryPointFn(),
                                  nullptr);
  Builder.SetCurrentDebugLocation(DL);
}

llvm::DIScope *IRGenDebugInfoImpl::getEntryPointFn() {
  // Lazily create EntryPointFn.
  if (!EntryPointFn) {
    EntryPointFn = DBuilder.createReplaceableCompositeType(
        llvm::dwarf::DW_TAG_subroutine_type,
        IGM.getSILModule().getASTContext().getEntryPointFunctionName(),
        MainFile, MainFile, 0);
  }
  return EntryPointFn;
}

llvm::DIScope *IRGenDebugInfoImpl::getOrCreateScope(const SILDebugScope *DS) {
  if (DS == nullptr)
    return MainFile;

  // Try to find it in the cache first.
  auto CachedScope = ScopeCache.find(DS);
  if (CachedScope != ScopeCache.end())
    return cast<llvm::DIScope>(CachedScope->second);

  // If this is an (inlined) function scope, the function may
  // not have been created yet.
  if (auto *SILFn = DS->Parent.dyn_cast<SILFunction *>()) {
    auto *FnScope = SILFn->getDebugScope();
    // FIXME: This is a bug in the SIL deserialization.
    if (!FnScope)
      SILFn->setDebugScope(DS);

    auto CachedScope = ScopeCache.find(FnScope);
    if (CachedScope != ScopeCache.end())
      return cast<llvm::DIScope>(CachedScope->second);

    // Force the debug info for the function to be emitted, even if it
    // is external or has been inlined.
    llvm::Function *Fn = nullptr;
    if (!SILFn->getName().empty() && !SILFn->isZombie())
      Fn = IGM.getAddrOfSILFunction(SILFn, NotForDefinition);
    auto *SP = emitFunction(*SILFn, Fn);

    // Cache it.
    ScopeCache[DS] = llvm::TrackingMDNodeRef(SP);
    return SP;
  }

  auto *ParentScope = DS->Parent.get<const SILDebugScope *>();
  llvm::DIScope *Parent = getOrCreateScope(ParentScope);
  assert(isa<llvm::DILocalScope>(Parent) && "not a local scope");

  if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
    return Parent;

  assert(DS->Parent && "lexical block must have a parent subprogram");
  auto L = getStartLocation(DS->Loc);
  llvm::DIFile *File = getOrCreateFile(L.filename);
  auto *DScope = DBuilder.createLexicalBlock(Parent, File, L.line, L.column);

  // Cache it.
  ScopeCache[DS] = llvm::TrackingMDNodeRef(DScope);
  return DScope;
}

void IRGenDebugInfoImpl::emitImport(ImportDecl *D) {
  if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
    return;

  assert(D->getModule() && "compiler-synthesized ImportDecl is incomplete");
  ImportedModule Imported = { D->getAccessPath(), D->getModule() };
  auto L = getFilenameAndLocation(*this, D);
  auto *File = getOrCreateFile(L.filename);
  createImportedModule(File, Imported, File, L.line);
  ImportedModules.insert(Imported.importedModule);
}

llvm::DISubprogram *IRGenDebugInfoImpl::emitFunction(SILFunction &SILFn,
                                                     llvm::Function *Fn) {
  auto *DS = SILFn.getDebugScope();
  assert(DS && "SIL function has no debug scope");
  (void)DS;
  return emitFunction(SILFn.getDebugScope(), Fn, SILFn.getRepresentation(),
                      SILFn.getLoweredType(), SILFn.getDeclContext());
}

llvm::DISubprogram *
IRGenDebugInfoImpl::emitFunction(const SILDebugScope *DS, llvm::Function *Fn,
                                 SILFunctionTypeRepresentation Rep,
                                 SILType SILTy, DeclContext *DeclCtx) {
  auto Cached = ScopeCache.find(DS);
  if (Cached != ScopeCache.end()) {
    auto SP = cast<llvm::DISubprogram>(Cached->second);
    // If we created the DISubprogram for a forward declaration,
    // attach it to the function now.
    if (!Fn->getSubprogram() && !Fn->isDeclaration())
      Fn->setSubprogram(SP);
    return SP;
  }

  // Some IRGen-generated helper functions don't have a corresponding
  // SIL function, hence the dyn_cast.
  auto *SILFn = DS ? DS->Parent.dyn_cast<SILFunction *>() : nullptr;

  StringRef LinkageName;
  if (Fn)
    LinkageName = Fn->getName();
  else if (DS)
    LinkageName = SILFn->getName();
  else
    llvm_unreachable("function has no mangled name");

  StringRef Name;
  if (DS) {
    if (DS->Loc.isSILFile())
      Name = SILFn->getName();
    else
      Name = getName(DS->Loc);
  }

  /// The source line used for the function prologue.
  unsigned ScopeLine = 0;
  SILLocation::FilenameAndLocation L;
  if (!DS || (SILFn && (SILFn->isBare() || SILFn->isThunk() ||
                        SILFn->isTransparent()))) {
    // Bare functions and thunks should not have any line numbers. This
    // is especially important for shared functions like reabstraction
    // thunk helpers, where DS->Loc is an arbitrary location of whichever use
    // was emitted first.
    L = *SILLocation::getCompilerGeneratedLoc();
  } else {
    L = decodeFilenameAndLocation(DS->Loc);
    ScopeLine = L.line;
  }

  auto Line = L.line;
  auto File = getOrCreateFile(L.filename);
  llvm::DIScope *Scope = MainModule;
  if (SILFn && SILFn->getDeclContext())
    Scope = getOrCreateContext(SILFn->getDeclContext()->getParent());

  // We know that main always comes from MainFile.
  if (LinkageName ==
      IGM.getSILModule().getASTContext().getEntryPointFunctionName()) {
    File = MainFile;
    Line = 1;
    Name = LinkageName;
  }

  CanSILFunctionType FnTy = getFunctionType(SILTy);
  auto Params = Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables
                    ? createParameterTypes(SILTy)
                    : nullptr;
  llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(Params);
  llvm::DITemplateParameterArray TemplateParameters = nullptr;
  llvm::DISubprogram *Decl = nullptr;

  // Various flags.
  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
  // Mark everything that is not visible from the source code (i.e.,
  // does not have a Swift name) as artificial, so the debugger can
  // ignore it. Explicit closures are exempt from this rule. We also
  // make an exception for toplevel code, which, although it does not
  // have a Swift name, does appear prominently in the source code.
  // ObjC thunks should also not show up in the linetable, because we
  // never want to set a breakpoint there.
  if ((Name.empty() &&
       LinkageName !=
           IGM.getSILModule().getASTContext().getEntryPointFunctionName() &&
       !isExplicitClosure(SILFn)) ||
      (Rep == SILFunctionTypeRepresentation::ObjCMethod) ||
      isAllocatingConstructor(Rep, DeclCtx)) {
    Flags |= llvm::DINode::FlagArtificial;
    ScopeLine = 0;
  }

  if (FnTy &&
      FnTy->getRepresentation() == SILFunctionType::Representation::Block)
    Flags |= llvm::DINode::FlagAppleBlock;

  // Get the throws information.
  llvm::DITypeArray Error = nullptr;
  if (FnTy)
    if (auto ErrorInfo = FnTy->getOptionalErrorResult()) {
      auto DTI = DebugTypeInfo::getFromTypeInfo(
          ErrorInfo->getReturnValueType(IGM.getSILModule(), FnTy,
                                        IGM.getMaximalTypeExpansionContext()),
          IGM.getTypeInfo(IGM.silConv.getSILType(
              *ErrorInfo, FnTy, IGM.getMaximalTypeExpansionContext())),
          false);
      Error = DBuilder.getOrCreateArray({getOrCreateType(DTI)}).get();
    }

  llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::toSPFlags(
      /*IsLocalToUnit=*/Fn ? Fn->hasInternalLinkage() : true,
      /*IsDefinition=*/true, /*IsOptimized=*/Opts.shouldOptimize());

  // Construct the DISubprogram.
  llvm::DISubprogram *SP = DBuilder.createFunction(
      Scope, Name, LinkageName, File, Line, DIFnTy, ScopeLine, Flags, SPFlags,
      TemplateParameters, Decl, Error);

  if (Fn && !Fn->isDeclaration())
    Fn->setSubprogram(SP);

  // RAUW the entry point function forward declaration with the real thing.
  if (LinkageName ==
      IGM.getSILModule().getASTContext().getEntryPointFunctionName()) {
    if (EntryPointFn) {
      assert(EntryPointFn->isTemporary() &&
             "more than one entry point function");
      EntryPointFn->replaceAllUsesWith(SP);
      llvm::MDNode::deleteTemporary(EntryPointFn);
    }
    EntryPointFn = SP;
  }

  if (!DS)
    return nullptr;

  ScopeCache[DS] = llvm::TrackingMDNodeRef(SP);
  return SP;
}

void IRGenDebugInfoImpl::emitArtificialFunction(IRBuilder &Builder,
                                                llvm::Function *Fn,
                                                SILType SILTy) {
  RegularLocation ALoc = RegularLocation::getAutoGeneratedLocation();
  const SILDebugScope *Scope = new (IGM.getSILModule()) SILDebugScope(ALoc);
  emitFunction(Scope, Fn, SILFunctionTypeRepresentation::Thin, SILTy);
  /// Reusing the current file would be wrong: An objc thunk, for example, could
  /// be triggered from any random location. Use a placeholder name instead.
  setCurrentLoc(Builder, Scope, ALoc);
}

bool IRGenDebugInfoImpl::handleFragmentDIExpr(
    const SILDIExprOperand &CurDIExprOp, SmallVectorImpl<uint64_t> &Operands) {
  assert(CurDIExprOp.getOperator() == SILDIExprOperator::Fragment);
  // Expecting a VarDecl that points to a field in an struct
  auto DIExprArgs = CurDIExprOp.args();
  auto *VD = dyn_cast_or_null<VarDecl>(DIExprArgs.size()?
                                       DIExprArgs[0].getAsDecl() : nullptr);
  assert(VD && "Expecting a VarDecl as the operand for "
               "DIExprOperator::Fragment");
  // Translate the based type
  DeclContext *ParentDecl = VD->getDeclContext();
  assert(ParentDecl && "VarDecl has no parent context?");
  SILType ParentSILType =
      IGM.getLoweredType(ParentDecl->getDeclaredTypeInContext());
  // Retrieve the offset & size of the field
  llvm::Constant *Offset =
      emitPhysicalStructMemberFixedOffset(IGM, ParentSILType, VD);
  auto *FieldTypeInfo = getPhysicalStructFieldTypeInfo(IGM, ParentSILType, VD);
  // FIXME: This will only happen if IRGen hasn't processed ParentSILType
  // (into its own representation) but we probably should ask IRGen to process
  // it right now.
  if (!FieldTypeInfo)
    return false;
  llvm::Type *FieldTy = FieldTypeInfo->getStorageType();
  // Doesn't support non-fixed type right now
  if (!Offset || !FieldTy)
    return false;

  uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
  uint64_t SizeInBits = IGM.DataLayout.getTypeSizeInBits(FieldTy);
  uint64_t OffsetInBits =
      Offset->getUniqueInteger().getLimitedValue() * SizeOfByte;

  // Translate to LLVM dbg intrinsic operands
  Operands.push_back(llvm::dwarf::DW_OP_LLVM_fragment);
  Operands.push_back(OffsetInBits);
  Operands.push_back(SizeInBits);

  return true;
}

bool IRGenDebugInfoImpl::buildDebugInfoExpression(
    const SILDebugVariable &VarInfo, SmallVectorImpl<uint64_t> &Operands) {
  assert(VarInfo.DIExpr && "SIL debug info expression not found");

  const auto &DIExpr = VarInfo.DIExpr;
  for (const SILDIExprOperand &ExprOperand : DIExpr.operands()) {
    switch (ExprOperand.getOperator()) {
    case SILDIExprOperator::Fragment:
      if (!handleFragmentDIExpr(ExprOperand, Operands))
        return false;
      break;
    case SILDIExprOperator::Dereference:
      Operands.push_back(llvm::dwarf::DW_OP_deref);
      break;
    case SILDIExprOperator::Plus:
      Operands.push_back(llvm::dwarf::DW_OP_plus);
      break;
    case SILDIExprOperator::Minus:
      Operands.push_back(llvm::dwarf::DW_OP_minus);
      break;
    case SILDIExprOperator::ConstUInt:
      Operands.push_back(llvm::dwarf::DW_OP_constu);
      Operands.push_back(*ExprOperand[1].getAsConstInt());
      break;
    case SILDIExprOperator::ConstSInt:
      Operands.push_back(llvm::dwarf::DW_OP_consts);
      Operands.push_back(*ExprOperand[1].getAsConstInt());
      break;
    case SILDIExprOperator::INVALID:
      return false;
    }
  }
  return true;
}

void IRGenDebugInfoImpl::emitVariableDeclaration(
    IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo DbgTy,
    const SILDebugScope *DS, Optional<SILLocation> DbgInstLoc,
    SILDebugVariable VarInfo, IndirectionKind Indirection,
    ArtificialKind Artificial) {
  assert(DS && "variable has no scope");

  if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
    return;

  // We cannot yet represent opened existentials.
  if (DbgTy.getType()->hasOpenedExistential())
    return;

  if (!DbgTy.getTypeSize())
    DbgTy.setSize(getStorageSize(IGM.DataLayout, Storage));

  auto *Scope = dyn_cast_or_null<llvm::DILocalScope>(getOrCreateScope(DS));
  assert(Scope && "variable has no local scope");
  auto DInstLoc = getStartLocation(DbgInstLoc);

  // FIXME: this should be the scope of the type's declaration.
  // If this is an argument, attach it to the current function scope.
  uint16_t ArgNo = VarInfo.ArgNo;
  if (ArgNo > 0) {
    while (isa<llvm::DILexicalBlock>(Scope))
      Scope = cast<llvm::DILexicalBlock>(Scope)->getScope();
  }
  assert(isa_and_nonnull<llvm::DIScope>(Scope) && "variable has no scope");
  llvm::DIFile *Unit = getFile(Scope);
  llvm::DIType *DITy = getOrCreateType(DbgTy);
  assert(DITy && "could not determine debug type of variable");
  if (VarInfo.Constant)
    DITy = DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_const_type, DITy);

  unsigned DInstLine = DInstLoc.line;

  // Self is always an artificial argument, so are variables without location.
  if (!DInstLine || (ArgNo > 0 && VarInfo.Name == IGM.Context.Id_self.str()))
    Artificial = ArtificialValue;

  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
  if (Artificial || DITy->isArtificial() || DITy == InternalType)
    Flags |= llvm::DINode::FlagArtificial;

  // Create the descriptor for the variable.
  unsigned DVarLine = DInstLine;
  uint16_t DVarCol = 0;
  if (VarInfo.Loc) {
    auto DVarLoc = getStartLocation(VarInfo.Loc);
    DVarLine = DVarLoc.line;
    DVarCol = DVarLoc.column;
  }
  llvm::DIScope *VarScope = Scope;
  if (ArgNo == 0 && VarInfo.Scope) {
    if (auto *VS = dyn_cast_or_null<llvm::DILocalScope>(
            getOrCreateScope(VarInfo.Scope))) {
      VarScope = VS;
    }
  }

  // Get or create the DILocalVariable.
  llvm::DILocalVariable *Var;
  // VarInfo.Name points into tail-allocated storage in debug_value insns.
  llvm::StringRef UniqueName = VarNames.insert(VarInfo.Name).first->getKey();
  VarID Key(VarScope, UniqueName, DVarLine, DVarCol);
  auto CachedVar = LocalVarCache.find(Key);
  if (CachedVar != LocalVarCache.end()) {
    Var = cast<llvm::DILocalVariable>(CachedVar->second);
  } else {
    // The llvm.dbg.value(undef) emitted for zero-sized variables get filtered
    // out by DwarfDebug::collectEntityInfo(), so all variables need to be
    // preserved even at -Onone.
    bool Preserve = true;
    if (ArgNo > 0)
      Var = DBuilder.createParameterVariable(
          VarScope, VarInfo.Name, ArgNo, Unit, DVarLine, DITy, Preserve, Flags);
    else
      Var = DBuilder.createAutoVariable(VarScope, VarInfo.Name, Unit, DVarLine,
                                        DITy, Preserve, Flags);
    LocalVarCache.insert({Key, llvm::TrackingMDNodeRef(Var)});
  }

  auto appendDIExpression =
      [&VarInfo, this](llvm::DIExpression *DIExpr) -> llvm::DIExpression * {
    if (VarInfo.DIExpr) {
      llvm::SmallVector<uint64_t, 2> Operands;
      if (!buildDebugInfoExpression(VarInfo, Operands))
        return nullptr;
      if (Operands.size())
        return llvm::DIExpression::append(DIExpr, Operands);
    }
    return DIExpr;
  };

  // Running variables for the current/previous piece.
  bool IsPiece = Storage.size() > 1;
  uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
  unsigned AlignInBits = SizeOfByte;
  unsigned OffsetInBits = 0;
  unsigned SizeInBits = 0;

  for (llvm::Value *Piece : Storage) {
    SmallVector<uint64_t, 3> Operands;
    if (Indirection == IndirectValue || Indirection == CoroIndirectValue)
      Operands.push_back(llvm::dwarf::DW_OP_deref);

    if (IsPiece) {
      // Advance the offset and align it for the next piece.
      OffsetInBits += llvm::alignTo(SizeInBits, AlignInBits);
      SizeInBits = IGM.DataLayout.getTypeSizeInBits(Piece->getType());
      AlignInBits = IGM.DataLayout.getABITypeAlignment(Piece->getType());
      if (!AlignInBits)
        AlignInBits = SizeOfByte;

      // Sanity checks.
#ifndef NDEBUG
      assert(SizeInBits && "zero-sized piece");
      if (getSizeInBits(Var)) {
        assert(SizeInBits < getSizeInBits(Var) && "piece covers entire var");
        assert(OffsetInBits + SizeInBits <= getSizeInBits(Var) &&
               "pars > totum");
      }
#endif

      // Add the piece DWARF expression.
      Operands.push_back(llvm::dwarf::DW_OP_LLVM_fragment);
      Operands.push_back(OffsetInBits);
      Operands.push_back(SizeInBits);
    }
    llvm::DIExpression *DIExpr = DBuilder.createExpression(Operands);
    // DW_OP_LLVM_fragment must be the last part of an DIExpr
    // so we can't append more if IsPiece is true.
    if (!IsPiece)
      DIExpr = appendDIExpression(DIExpr);
    if (DIExpr)
      emitDbgIntrinsic(
          Builder, Piece, Var, DIExpr, DInstLine, DInstLoc.column, Scope, DS,
          Indirection == CoroDirectValue || Indirection == CoroIndirectValue);
  }

  // Emit locationless intrinsic for variables that were optimized away.
  if (Storage.empty()) {
    if (auto *DIExpr = appendDIExpression(DBuilder.createExpression()))
      emitDbgIntrinsic(Builder, llvm::ConstantInt::get(IGM.Int64Ty, 0), Var,
                       DIExpr, DInstLine, DInstLoc.column, Scope, DS,
                       Indirection == CoroDirectValue ||
                           Indirection == CoroIndirectValue);
  }
}

void IRGenDebugInfoImpl::emitDbgIntrinsic(
    IRBuilder &Builder, llvm::Value *Storage, llvm::DILocalVariable *Var,
    llvm::DIExpression *Expr, unsigned Line, unsigned Col,
    llvm::DILocalScope *Scope, const SILDebugScope *DS, bool InCoroContext) {
  // Set the location/scope of the intrinsic.
  auto *InlinedAt = createInlinedAt(DS);
  auto DL =
      llvm::DILocation::get(IGM.getLLVMContext(), Line, Col, Scope, InlinedAt);
  auto *BB = Builder.GetInsertBlock();

  // An alloca may only be described by exactly one dbg.declare.
  if (isa<llvm::AllocaInst>(Storage) &&
      !llvm::FindDbgDeclareUses(Storage).empty())
    return;

  // Fragment DIExpression cannot cover the whole variable
  // or going out-of-bound.
  if (auto Fragment = Expr->getFragmentInfo())
    if (auto VarSize = Var->getSizeInBits()) {
      unsigned FragSize = Fragment->SizeInBits;
      unsigned FragOffset = Fragment->OffsetInBits;
      if (FragOffset + FragSize > *VarSize ||
          FragSize == *VarSize) {
        // Drop the fragment part
        assert(Expr->isValid());
        // Since this expression is valid, DW_OP_LLVM_fragment
        // and its arguments must be the last 3 elements.
        auto OrigElements = Expr->getElements();
        Expr = DBuilder.createExpression(OrigElements.drop_back(3));
      }
    }

  // A dbg.declare is only meaningful if there is a single alloca for
  // the variable that is live throughout the function.
  if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
    auto *ParentBB = Alloca->getParent();
    auto InsertBefore = std::next(Alloca->getIterator());
    if (InsertBefore != ParentBB->end())
      DBuilder.insertDeclare(Alloca, Var, Expr, DL, &*InsertBefore);
    else
      DBuilder.insertDeclare(Alloca, Var, Expr, DL, ParentBB);
  } else if ((isa<llvm::IntrinsicInst>(Storage) &&
              cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID() ==
                  llvm::Intrinsic::coro_alloca_get)) {
    // FIXME: The live range of a coroutine alloca within the function may be
    // limited, so using a dbg.addr instead of a dbg.declare would be more
    // appropriate.
    DBuilder.insertDeclare(Storage, Var, Expr, DL, BB);
  } else if (InCoroContext) {
    // Function arguments in async functions are emitted without a shadow copy
    // (that would interfer with coroutine splitting) but with a dbg.declare to
    // give CoroSplit.cpp license to emit a shadow copy for them pointing inside
    // the Swift Context argument that is valid throughout the function.
    auto &EntryBlock = BB->getParent()->getEntryBlock();
    if (auto *InsertBefore = &*EntryBlock.getFirstInsertionPt())
      DBuilder.insertDeclare(Storage, Var, Expr, DL, InsertBefore);
    else
      DBuilder.insertDeclare(Storage, Var, Expr, DL, &EntryBlock);
  } else {
    // Insert a dbg.value at the current insertion point.
    if (isa<llvm::Argument>(Storage) && !Var->getArg() &&
        BB->getFirstNonPHIOrDbg())
      // SelectionDAGISel only generates debug info for a dbg.value
      // that is associated with a llvm::Argument if either its !DIVariable
      // is marked as argument or there is no non-debug intrinsic instruction
      // before it. So In the case of associating a llvm::Argument with a
      // non-argument debug variable -- usually via a !DIExpression -- we
      // need to make sure that dbg.value is before any non-phi / no-dbg
      // instruction.
      DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL,
                                       BB->getFirstNonPHIOrDbg());
    else
      DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, BB);
  }
}

void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
    llvm::GlobalVariable *Var, StringRef Name, StringRef LinkageName,
    DebugTypeInfo DbgTy, bool IsLocalToUnit, bool InFixedBuffer,
    Optional<SILLocation> Loc) {
  if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
    return;

  // TODO: fix demangling for C++ types (SR-13223).
  if (swift::TypeBase *ty = DbgTy.getType()) {
    if (MetatypeType *metaTy = dyn_cast<MetatypeType>(ty))
      ty = metaTy->getInstanceType().getPointer();
    if (ty->getStructOrBoundGenericStruct() &&
        isa_and_nonnull<clang::CXXRecordDecl>(
            ty->getStructOrBoundGenericStruct()->getClangDecl()))
      return;
  }

  llvm::DIType *DITy = getOrCreateType(DbgTy);
  VarDecl *VD = nullptr;
  if (Loc)
    VD = dyn_cast_or_null<VarDecl>(Loc->getAsASTNode<Decl>());
  if (!VD || VD->isLet())
    DITy = DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_const_type, DITy);

  if (DITy->isArtificial() || DITy == InternalType || !Loc)
    // FIXME: Really these should be marked as artificial, but LLVM
    // currently has no support for flags to be put on global
    // variables. In the mean time, elide these variables, they
    // would confuse both the user and LLDB.
    return;

  if (InFixedBuffer)
    DITy = createFixedValueBufferStruct(DITy);

  auto L = getStartLocation(Loc);
  auto File = getOrCreateFile(L.filename);

  // Emit it as global variable of the current module.
  llvm::DIExpression *Expr = nullptr;
  if (!Var)
    Expr = DBuilder.createConstantValueExpression(0);
  auto *GV = DBuilder.createGlobalVariableExpression(
      MainModule, Name, LinkageName, File, L.line, DITy, IsLocalToUnit, true,
      Expr);
  if (Var)
    Var->addDebugInfo(GV);
}

void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
                                          llvm::Value *Metadata, unsigned Depth,
                                          unsigned Index, StringRef Name) {
  if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
    return;

  // Don't emit debug info in transparent functions.
  auto *DS = IGF.getDebugScope();
  if (!DS || DS->getInlinedFunction()->isTransparent())
    return;

  llvm::SmallString<8> Buf;
  static const char *Tau = u8"\u03C4";
  llvm::raw_svector_ostream OS(Buf);
  OS << '$' << Tau << '_' << Depth << '_' << Index;
  auto DbgTy = DebugTypeInfo::getArchetype(
      getMetadataType(Name)->getDeclaredInterfaceType().getPointer(),
      Metadata->getType(), Size(CI.getTargetInfo().getPointerWidth(0)),
      Alignment(CI.getTargetInfo().getPointerAlign(0)));
  emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(),
                          {}, {OS.str().str(), 0, false},
                          // swift.type is already a pointer type,
                          // having a shadow copy doesn't add another
                          // layer of indirection.
                          IGF.isAsync() ? CoroDirectValue : DirectValue,
                          ArtificialValue);
}

SILLocation::FilenameAndLocation IRGenDebugInfoImpl::decodeSourceLoc(SourceLoc SL) {
  auto &Cached = FilenameAndLocationCache[SL.getOpaquePointerValue()];
  if (Cached.filename.empty())
    Cached = sanitizeCodeViewFilenameAndLocation(SILLocation::decode(SL, SM));
  return Cached;
}

} // anonymous namespace

std::unique_ptr<IRGenDebugInfo> IRGenDebugInfo::createIRGenDebugInfo(
    const IRGenOptions &Opts, ClangImporter &CI, IRGenModule &IGM,
    llvm::Module &M, StringRef MainOutputFilenameForDebugInfo,
    StringRef PrivateDiscriminator) {
  return std::make_unique<IRGenDebugInfoImpl>(
      Opts, CI, IGM, M, MainOutputFilenameForDebugInfo, PrivateDiscriminator);
}

IRGenDebugInfo::~IRGenDebugInfo() {}

// Forwarding to the private implementation.
void IRGenDebugInfo::finalize() {
  static_cast<IRGenDebugInfoImpl *>(this)->finalize();
}

void IRGenDebugInfo::setCurrentLoc(IRBuilder &Builder, const SILDebugScope *DS,
                                   SILLocation Loc) {
  static_cast<IRGenDebugInfoImpl *>(this)->setCurrentLoc(Builder, DS, Loc);
}

void IRGenDebugInfo::addFailureMessageToCurrentLoc(IRBuilder &Builder,
                                                   StringRef failureMsg) {
  static_cast<IRGenDebugInfoImpl *>(this)->addFailureMessageToCurrentLoc(
      Builder, failureMsg);
}

void IRGenDebugInfo::clearLoc(IRBuilder &Builder) {
  static_cast<IRGenDebugInfoImpl *>(this)->clearLoc(Builder);
}

void IRGenDebugInfo::pushLoc() {
  static_cast<IRGenDebugInfoImpl *>(this)->pushLoc();
}

void IRGenDebugInfo::popLoc() {
  static_cast<IRGenDebugInfoImpl *>(this)->popLoc();
}

void IRGenDebugInfo::setInlinedTrapLocation(IRBuilder &Builder,
                                            const SILDebugScope *Scope) {
  static_cast<IRGenDebugInfoImpl *>(this)->setInlinedTrapLocation(Builder,
                                                                  Scope);
}

void IRGenDebugInfo::setEntryPointLoc(IRBuilder &Builder) {
  static_cast<IRGenDebugInfoImpl *>(this)->setEntryPointLoc(Builder);
}

llvm::DIScope *IRGenDebugInfo::getEntryPointFn() {
  return static_cast<IRGenDebugInfoImpl *>(this)->getEntryPointFn();
}

llvm::DIScope *IRGenDebugInfo::getOrCreateScope(const SILDebugScope *DS) {
  return static_cast<IRGenDebugInfoImpl *>(this)->getOrCreateScope(DS);
}

void IRGenDebugInfo::emitImport(ImportDecl *D) {
  static_cast<IRGenDebugInfoImpl *>(this)->emitImport(D);
}

llvm::DISubprogram *
IRGenDebugInfo::emitFunction(const SILDebugScope *DS, llvm::Function *Fn,
                             SILFunctionTypeRepresentation Rep, SILType Ty,
                             DeclContext *DeclCtx, GenericEnvironment *GE) {
  return static_cast<IRGenDebugInfoImpl *>(this)->emitFunction(DS, Fn, Rep, Ty,
                                                               DeclCtx);
}

llvm::DISubprogram *IRGenDebugInfo::emitFunction(SILFunction &SILFn,
                                                 llvm::Function *Fn) {
  return static_cast<IRGenDebugInfoImpl *>(this)->emitFunction(SILFn, Fn);
}

void IRGenDebugInfo::emitArtificialFunction(IRBuilder &Builder,
                                            llvm::Function *Fn, SILType SILTy) {
  static_cast<IRGenDebugInfoImpl *>(this)->emitArtificialFunction(Builder, Fn,
                                                                  SILTy);
}

void IRGenDebugInfo::emitVariableDeclaration(
    IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo Ty,
    const SILDebugScope *DS, Optional<SILLocation> VarLoc, SILDebugVariable VarInfo,
    IndirectionKind Indirection, ArtificialKind Artificial) {
  static_cast<IRGenDebugInfoImpl *>(this)->emitVariableDeclaration(
      Builder, Storage, Ty, DS, VarLoc, VarInfo, Indirection, Artificial);
}

void IRGenDebugInfo::emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
                                      llvm::DILocalVariable *Var,
                                      llvm::DIExpression *Expr, unsigned Line,
                                      unsigned Col, llvm::DILocalScope *Scope,
                                      const SILDebugScope *DS,
                                      bool InCoroContext) {
  static_cast<IRGenDebugInfoImpl *>(this)->emitDbgIntrinsic(
      Builder, Storage, Var, Expr, Line, Col, Scope, DS, InCoroContext);
}

void IRGenDebugInfo::emitGlobalVariableDeclaration(
    llvm::GlobalVariable *Storage, StringRef Name, StringRef LinkageName,
    DebugTypeInfo DebugType, bool IsLocalToUnit, bool InFixedBuffer,
    Optional<SILLocation> Loc) {
  static_cast<IRGenDebugInfoImpl *>(this)->emitGlobalVariableDeclaration(
      Storage, Name, LinkageName, DebugType, IsLocalToUnit, InFixedBuffer, Loc);
}

void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
                                      unsigned Depth, unsigned Index,
                                      StringRef Name) {
  static_cast<IRGenDebugInfoImpl *>(this)->emitTypeMetadata(IGF, Metadata,
                                                            Depth, Index, Name);
}

llvm::DIBuilder &IRGenDebugInfo::getBuilder() {
  return static_cast<IRGenDebugInfoImpl *>(this)->getBuilder();
}

SILLocation::FilenameAndLocation IRGenDebugInfo::decodeSourceLoc(SourceLoc SL) {
  return static_cast<IRGenDebugInfoImpl *>(this)->decodeSourceLoc(SL);
}

AutoRestoreLocation::AutoRestoreLocation(IRGenDebugInfo *DI, IRBuilder &Builder)
    : DI(DI), Builder(Builder) {
  if (DI)
    SavedLocation = Builder.getCurrentDebugLocation();
}

/// Autorestore everything back to normal.
AutoRestoreLocation::~AutoRestoreLocation() {
  if (DI)
    Builder.SetCurrentDebugLocation(SavedLocation);
}

ArtificialLocation::ArtificialLocation(const SILDebugScope *DS,
                                       IRGenDebugInfo *DI, IRBuilder &Builder)
    : AutoRestoreLocation(DI, Builder) {
  if (DI) {
    unsigned Line = 0;
    auto *Scope = DI->getOrCreateScope(DS);
    if (static_cast<IRGenDebugInfoImpl *>(DI)->getDebugInfoFormat() ==
        IRGenDebugInfoFormat::CodeView) {
      // In CodeView, line zero is not an artificial line location and so we
      // try to use the location of the scope.
      if (auto *LB = dyn_cast<llvm::DILexicalBlock>(Scope))
        Line = LB->getLine();
      else if (auto *SP = dyn_cast<llvm::DISubprogram>(Scope))
        Line = SP->getLine();
    }
    auto DL = llvm::DILocation::get(Scope->getContext(), Line, 0, Scope);
    Builder.SetCurrentDebugLocation(DL);
  }
}

PrologueLocation::PrologueLocation(IRGenDebugInfo *DI, IRBuilder &Builder)
    : AutoRestoreLocation(DI, Builder) {
  if (DI)
    DI->clearLoc(Builder);
}
