text: //===--- 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 "IRBuilder.h"
  #include "swift/AST/ASTDemangler.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/Constants.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"
  
  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) {
    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;
    llvm::StringMap<llvm::TrackingMDNodeRef> RuntimeErrorFnCache;
    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,
                                     StringRef outlinedFromName = StringRef());
    llvm::DISubprogram *emitFunction(SILFunction &SILFn, llvm::Function *Fn);
    void emitArtificialFunction(IRBuilder &Builder, llvm::Function *Fn,
                                SILType SILTy);
    void emitOutlinedFunction(IRBuilder &Builder,
                              llvm::Function *Fn,
                              StringRef outlinedFromName);
  
    /// 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);
  
    /// Emit a dbg.declare at the current insertion point in Builder.
    void emitVariableDeclaration(IRBuilder &Builder,
                                 ArrayRef<llvm::Value *> Storage,
                                 DebugTypeInfo Ty, const SILDebugScope *DS,
                                 Optional<SILLocation> VarLoc,
                                 SILDebugVariable VarInfo,
                                 IndirectionKind = DirectValue,
                                 ArtificialKind = RealValue,
                                 AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
  
    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,
                          AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
  
    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.
        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();
        }
      }
  
      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 interferes 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:
      case TypeKind::ParameterizedProtocol: {
        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::Pack:
      case TypeKind::PackExpansion:
        llvm_unreachable("Unimplemented!");
  
      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::SequenceArchetype: {
        auto *Archetype = BaseTy->castTo<ArchetypeType>();
        AssociatedTypeDecl *assocType = nullptr;
        if (auto depMemTy = Archetype->getInterfaceType()
                ->getAs<DependentMemberType>())
          assocType = depMemTy->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:
      case TypeKind::SILMoveOnly:
  
        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.getSDKPath();
    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 command 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);
  
    llvm::DISubprogram *TrapSP;
    auto It = RuntimeErrorFnCache.find(failureMsg);
    if (It != RuntimeErrorFnCache.end())
      TrapSP = llvm::cast<llvm::DISubprogram>(It->second);
    else {
      std::string FuncName = "Swift runtime failure: ";
      FuncName += failureMsg;
      llvm::DIFile *File = getOrCreateFile({});
      TrapSP = DBuilder.createFunction(
          File, FuncName, StringRef(), File, 0,
          DIFnTy, 0, llvm::DINode::FlagArtificial,
          llvm::DISubprogram::SPFlagDefinition, nullptr, nullptr, nullptr);
      RuntimeErrorFnCache.insert({failureMsg, llvm::TrackingMDNodeRef(TrapSP)});
    }
  
    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,
                                   StringRef outlinedFromName) {
    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 (!outlinedFromName.empty())
      LinkageName = outlinedFromName;
    else 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);
  }
  
  void IRGenDebugInfoImpl::emitOutlinedFunction(IRBuilder &Builder,
                                                llvm::Function *Fn,
                                                StringRef outlinedFromName) {
    RegularLocation ALoc = RegularLocation::getAutoGeneratedLocation();
    const SILDebugScope *Scope = new (IGM.getSILModule()) SILDebugScope(ALoc);
    emitFunction(Scope, Fn, SILFunctionTypeRepresentation::Thin, SILType(),
                 nullptr, outlinedFromName);
    /// 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, AddrDbgInstrKind AddrDInstrKind) {
    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,
            AddrDInstrKind);
    }
  
    // 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,
                         AddrDInstrKind);
    }
  }
  
  namespace {
  
  /// A helper struct that is used by emitDbgIntrinsic to factor redundant code.
  struct DbgIntrinsicEmitter {
    PointerUnion<llvm::BasicBlock *, llvm::Instruction *> InsertPt;
    irgen::IRBuilder &IRBuilder;
    llvm::DIBuilder &DIBuilder;
    AddrDbgInstrKind ForceDbgDeclare;
  
    /// Initialize the emitter and initialize the emitter to assume that it is
    /// going to insert an llvm.dbg.declare or an llvm.dbg.addr either at the
    /// current "generalized insertion point" of the IRBuilder. The "generalized
    /// insertion point" is
    DbgIntrinsicEmitter(irgen::IRBuilder &IRBuilder, llvm::DIBuilder &DIBuilder,
                        AddrDbgInstrKind ForceDebugDeclare)
        : InsertPt(), IRBuilder(IRBuilder), DIBuilder(DIBuilder),
          ForceDbgDeclare(ForceDebugDeclare) {
      auto *ParentBB = IRBuilder.GetInsertBlock();
      auto InsertBefore = IRBuilder.GetInsertPoint();
  
      if (InsertBefore != ParentBB->end())
        InsertPt = &*InsertBefore;
      else
        InsertPt = ParentBB;
    }
  
    ///
  
    llvm::Instruction *insert(llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
                              llvm::DIExpression *Expr,
                              const llvm::DILocation *DL) {
      if (auto *Inst = InsertPt.dyn_cast<llvm::Instruction *>()) {
        return insert(Addr, VarInfo, Expr, DL, Inst);
      } else {
        return insert(Addr, VarInfo, Expr, DL,
                      InsertPt.get<llvm::BasicBlock *>());
      }
    }
  
    llvm::Instruction *insert(llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
                              llvm::DIExpression *Expr,
                              const llvm::DILocation *DL,
                              llvm::Instruction *InsertBefore) {
      if (ForceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
        return DIBuilder.insertDeclare(Addr, VarInfo, Expr, DL, InsertBefore);
      return DIBuilder.insertDbgAddrIntrinsic(Addr, VarInfo, Expr, DL,
                                              InsertBefore);
    }
  
    llvm::Instruction *insert(llvm::Value *Addr, llvm::DILocalVariable *VarInfo,
                              llvm::DIExpression *Expr,
                              const llvm::DILocation *DL,
                              llvm::BasicBlock *Block) {
      if (ForceDbgDeclare == AddrDbgInstrKind::DbgDeclare)
        return DIBuilder.insertDeclare(Addr, VarInfo, Expr, DL, Block);
      return DIBuilder.insertDbgAddrIntrinsic(Addr, VarInfo, Expr, DL, Block);
    }
  };
  
  } // namespace
  
  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,
      AddrDbgInstrKind AddrDInstKind) {
    // Set the location/scope of the intrinsic.
    auto *InlinedAt = createInlinedAt(DS);
    auto DL =
        llvm::DILocation::get(IGM.getLLVMContext(), Line, Col, Scope, InlinedAt);
  
    // 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));
        }
      }
    }
  
    auto *ParentBlock = Builder.GetInsertBlock();
  
    // First before we do anything, check if we have an Undef. In this case, we
    // /always/ emit an llvm.dbg.value of undef.
    // If we have undef, always emit a llvm.dbg.value in the current position.
    if (isa<llvm::UndefValue>(Storage)) {
      DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, ParentBlock);
      return;
    }
  
    DbgIntrinsicEmitter inserter{Builder, DBuilder, AddrDInstKind};
  
    // If we have a single alloca...
    if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
      auto InsertBefore = Builder.GetInsertPoint();
  
      if (AddrDInstKind == AddrDbgInstrKind::DbgDeclare) {
        ParentBlock = Alloca->getParent();
        InsertBefore = std::next(Alloca->getIterator());
      }
  
      if (InsertBefore != ParentBlock->end()) {
        inserter.insert(Alloca, Var, Expr, DL, &*InsertBefore);
      } else {
        inserter.insert(Alloca, Var, Expr, DL, ParentBlock);
      }
      return;
    }
  
    if ((isa<llvm::IntrinsicInst>(Storage) &&
         cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID() ==
             llvm::Intrinsic::coro_alloca_get)) {
      inserter.insert(Storage, Var, Expr, DL, ParentBlock);
      return;
    }
  
    if (InCoroContext) {
      PointerUnion<llvm::BasicBlock *, llvm::Instruction *> InsertPt;
  
      // If we have a dbg.declare, we are relying on a contract with the coroutine
      // splitter that in split coroutines we always create debug info for values
      // in the coroutine context by creating a llvm.dbg.declare for the variable
      // in the entry block of each funclet.
      if (AddrDInstKind == AddrDbgInstrKind::DbgDeclare) {
        // Function arguments in async functions are emitted without a shadow copy
        // (that would interfere with coroutine splitting) but with a
        // llvm.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 = ParentBlock->getParent()->getEntryBlock();
        if (auto *InsertBefore = &*EntryBlock.getFirstInsertionPt()) {
          InsertPt = InsertBefore;
        } else {
          InsertPt = &EntryBlock;
        }
      } else {
        // For llvm.dbg.addr, we just want to insert the intrinsic at the current
        // insertion point. This is because our contract with the coroutine
        // splitter is that the coroutine splitter just needs to emit the
        // llvm.dbg.addr where we placed them. It shouldn't move them or do
        // anything special with it. Instead, we have previously inserted extra
        // debug_value clones previously after each instruction at the SIL level
        // that corresponds with a funclet edge. This operation effectively sets
        // up the rest of the pipeline to be stupid and just emit the
        // llvm.dbg.addr in the correct places. This is done by the SILOptimizer
        // pass DebugInfoCanonicalizer.
        auto InsertBefore = Builder.GetInsertPoint();
        if (InsertBefore != ParentBlock->end()) {
          InsertPt = &*InsertBefore;
        } else {
          InsertPt = ParentBlock;
        }
      }
  
      // Ok, we now have our insert pt. Call the appropriate operations.
      assert(InsertPt);
      if (auto *InsertBefore = InsertPt.dyn_cast<llvm::Instruction *>()) {
        inserter.insert(Storage, Var, Expr, DL, InsertBefore);
      } else {
        inserter.insert(Storage, Var, Expr, DL,
                        InsertPt.get<llvm::BasicBlock *>());
      }
      return;
    }
  
    // Insert a dbg.value at the current insertion point.
    if (isa<llvm::Argument>(Storage) && !Var->getArg() &&
        ParentBlock->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,
                                       ParentBlock->getFirstNonPHIOrDbg());
    else
      DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, ParentBlock);
  }
  
  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::emitOutlinedFunction(IRBuilder &Builder,
                                            llvm::Function *Fn, StringRef name) {
    static_cast<IRGenDebugInfoImpl *>(this)->emitOutlinedFunction(Builder, Fn,
                                                                  name);
  }
  void IRGenDebugInfo::emitVariableDeclaration(
      IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo Ty,
      const SILDebugScope *DS, Optional<SILLocation> VarLoc,
      SILDebugVariable VarInfo, IndirectionKind Indirection,
      ArtificialKind Artificial, AddrDbgInstrKind AddrDInstKind) {
    static_cast<IRGenDebugInfoImpl *>(this)->emitVariableDeclaration(
        Builder, Storage, Ty, DS, VarLoc, VarInfo, Indirection, Artificial,
        AddrDInstKind);
  }
  
  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,
                                        AddrDbgInstrKind AddrDInstKind) {
    static_cast<IRGenDebugInfoImpl *>(this)->emitDbgIntrinsic(
        Builder, Storage, Var, Expr, Line, Col, Scope, DS, InCoroContext,
        AddrDInstKind);
  }
  
  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);
  }
  