//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This is the source-level debug info generator for llvm translation.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H
#define LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H

#include "CGBuilder.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Allocator.h"

namespace llvm {
class MDNode;
}

namespace clang {
class ClassTemplateSpecializationDecl;
class GlobalDecl;
class ModuleMap;
class ObjCInterfaceDecl;
class ObjCIvarDecl;
class UsingDecl;
class VarDecl;
enum class DynamicInitKind : unsigned;

namespace CodeGen {
class CodeGenModule;
class CodeGenFunction;
class CGBlockInfo;

/// This class gathers all debug information during compilation and is
/// responsible for emitting to llvm globals or pass directly to the
/// backend.
class CGDebugInfo {
  friend class ApplyDebugLocation;
  friend class SaveAndRestoreLocation;
  CodeGenModule &CGM;
  const codegenoptions::DebugInfoKind DebugKind;
  bool DebugTypeExtRefs;
  llvm::DIBuilder DBuilder;
  llvm::DICompileUnit *TheCU = nullptr;
  ModuleMap *ClangModuleMap = nullptr;
  ASTSourceDescriptor PCHDescriptor;
  SourceLocation CurLoc;
  llvm::MDNode *CurInlinedAt = nullptr;
  llvm::DIType *VTablePtrType = nullptr;
  llvm::DIType *ClassTy = nullptr;
  llvm::DICompositeType *ObjTy = nullptr;
  llvm::DIType *SelTy = nullptr;
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
  llvm::DIType *SingletonId = nullptr;
#include "clang/Basic/OpenCLImageTypes.def"
  llvm::DIType *OCLSamplerDITy = nullptr;
  llvm::DIType *OCLEventDITy = nullptr;
  llvm::DIType *OCLClkEventDITy = nullptr;
  llvm::DIType *OCLQueueDITy = nullptr;
  llvm::DIType *OCLNDRangeDITy = nullptr;
  llvm::DIType *OCLReserveIDDITy = nullptr;
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
  llvm::DIType *Id##Ty = nullptr;
#include "clang/Basic/OpenCLExtensionTypes.def"

  /// Cache of previously constructed Types.
  llvm::DenseMap<const void *, llvm::TrackingMDRef> TypeCache;

  std::map<llvm::StringRef, llvm::StringRef, std::greater<llvm::StringRef>>
      DebugPrefixMap;

  /// Cache that maps VLA types to size expressions for that type,
  /// represented by instantiated Metadata nodes.
  llvm::SmallDenseMap<QualType, llvm::Metadata *> SizeExprCache;

  /// Callbacks to use when printing names and types.
  class PrintingCallbacks final : public clang::PrintingCallbacks {
    const CGDebugInfo &Self;

  public:
    PrintingCallbacks(const CGDebugInfo &Self) : Self(Self) {}
    std::string remapPath(StringRef Path) const override {
      return Self.remapDIPath(Path);
    }
  };
  PrintingCallbacks PrintCB = {*this};

  struct ObjCInterfaceCacheEntry {
    const ObjCInterfaceType *Type;
    llvm::DIType *Decl;
    llvm::DIFile *Unit;
    ObjCInterfaceCacheEntry(const ObjCInterfaceType *Type, llvm::DIType *Decl,
                            llvm::DIFile *Unit)
        : Type(Type), Decl(Decl), Unit(Unit) {}
  };

  /// Cache of previously constructed interfaces which may change.
  llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;

  /// Cache of forward declarations for methods belonging to the interface.
  /// The extra bit on the DISubprogram specifies whether a method is
  /// "objc_direct".
  llvm::DenseMap<const ObjCInterfaceDecl *,
                 std::vector<llvm::PointerIntPair<llvm::DISubprogram *, 1>>>
      ObjCMethodCache;

  /// Cache of references to clang modules and precompiled headers.
  llvm::DenseMap<const Module *, llvm::TrackingMDRef> ModuleCache;

  /// List of interfaces we want to keep even if orphaned.
  std::vector<void *> RetainedTypes;

  /// Cache of forward declared types to RAUW at the end of compilation.
  std::vector<std::pair<const TagType *, llvm::TrackingMDRef>> ReplaceMap;

  /// Cache of replaceable forward declarations (functions and
  /// variables) to RAUW at the end of compilation.
  std::vector<std::pair<const DeclaratorDecl *, llvm::TrackingMDRef>>
      FwdDeclReplaceMap;

  /// Keep track of our current nested lexical block.
  std::vector<llvm::TypedTrackingMDRef<llvm::DIScope>> LexicalBlockStack;
  llvm::DenseMap<const Decl *, llvm::TrackingMDRef> RegionMap;
  /// Keep track of LexicalBlockStack counter at the beginning of a
  /// function. This is used to pop unbalanced regions at the end of a
  /// function.
  std::vector<unsigned> FnBeginRegionCount;

  /// This is a storage for names that are constructed on demand. For
  /// example, C++ destructors, C++ operators etc..
  llvm::BumpPtrAllocator DebugInfoNames;
  StringRef CWDName;

  llvm::DenseMap<const char *, llvm::TrackingMDRef> DIFileCache;
  llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> SPCache;
  /// Cache declarations relevant to DW_TAG_imported_declarations (C++
  /// using declarations) that aren't covered by other more specific caches.
  llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
  llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NamespaceCache;
  llvm::DenseMap<const NamespaceAliasDecl *, llvm::TrackingMDRef>
      NamespaceAliasCache;
  llvm::DenseMap<const Decl *, llvm::TypedTrackingMDRef<llvm::DIDerivedType>>
      StaticDataMemberCache;

  using ParamDecl2StmtTy = llvm::DenseMap<const ParmVarDecl *, const Stmt *>;
  using Param2DILocTy =
      llvm::DenseMap<const ParmVarDecl *, llvm::DILocalVariable *>;

  /// The key is coroutine real parameters, value is coroutine move parameters.
  ParamDecl2StmtTy CoroutineParameterMappings;
  /// The key is coroutine real parameters, value is DIVariable in LLVM IR.
  Param2DILocTy ParamDbgMappings;

  /// Helper functions for getOrCreateType.
  /// @{
  /// Currently the checksum of an interface includes the number of
  /// ivars and property accessors.
  llvm::DIType *CreateType(const BuiltinType *Ty);
  llvm::DIType *CreateType(const ComplexType *Ty);
  llvm::DIType *CreateType(const AutoType *Ty);
  llvm::DIType *CreateType(const ExtIntType *Ty);
  llvm::DIType *CreateQualifiedType(QualType Ty, llvm::DIFile *Fg,
                                    TypeLoc TL = TypeLoc());
  llvm::DIType *CreateQualifiedType(const FunctionProtoType *Ty,
                                    llvm::DIFile *Fg);
  llvm::DIType *CreateType(const TypedefType *Ty, llvm::DIFile *Fg);
  llvm::DIType *CreateType(const TemplateSpecializationType *Ty,
                           llvm::DIFile *Fg);
  llvm::DIType *CreateType(const ObjCObjectPointerType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const PointerType *Ty, llvm::DIFile *F,
                           TypeLoc TL = TypeLoc());
  llvm::DIType *CreateType(const BlockPointerType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const FunctionType *Ty, llvm::DIFile *F,
                           TypeLoc TL = TypeLoc());
  /// Get structure or union type.
  llvm::DIType *CreateType(const RecordType *Tyg);
  llvm::DIType *CreateTypeDefinition(const RecordType *Ty);
  llvm::DICompositeType *CreateLimitedType(const RecordType *Ty);
  void CollectContainingType(const CXXRecordDecl *RD,
                             llvm::DICompositeType *CT);
  /// Get Objective-C interface type.
  llvm::DIType *CreateType(const ObjCInterfaceType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateTypeDefinition(const ObjCInterfaceType *Ty,
                                     llvm::DIFile *F);
  /// Get Objective-C object type.
  llvm::DIType *CreateType(const ObjCObjectType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const ObjCTypeParamType *Ty, llvm::DIFile *Unit);

  llvm::DIType *CreateType(const VectorType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const ConstantMatrixType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const ArrayType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const LValueReferenceType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const RValueReferenceType *Ty, llvm::DIFile *Unit);
  llvm::DIType *CreateType(const MemberPointerType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const AtomicType *Ty, llvm::DIFile *F);
  llvm::DIType *CreateType(const PipeType *Ty, llvm::DIFile *F);
  /// Get enumeration type.
  llvm::DIType *CreateEnumType(const EnumType *Ty);
  llvm::DIType *CreateTypeDefinition(const EnumType *Ty);
  /// Look up the completed type for a self pointer in the TypeCache and
  /// create a copy of it with the ObjectPointer and Artificial flags
  /// set. If the type is not cached, a new one is created. This should
  /// never happen though, since creating a type for the implicit self
  /// argument implies that we already parsed the interface definition
  /// and the ivar declarations in the implementation.
  llvm::DIType *CreateSelfType(const QualType &QualTy, llvm::DIType *Ty);
  /// @}

  /// Get the type from the cache or return null type if it doesn't
  /// exist.
  llvm::DIType *getTypeOrNull(const QualType);
  /// Return the debug type for a C++ method.
  /// \arg CXXMethodDecl is of FunctionType. This function type is
  /// not updated to include implicit \c this pointer. Use this routine
  /// to get a method type which includes \c this pointer.
  llvm::DISubroutineType *getOrCreateMethodType(const CXXMethodDecl *Method,
                                                llvm::DIFile *F, bool decl);
  llvm::DISubroutineType *
  getOrCreateInstanceMethodType(QualType ThisPtr, const FunctionProtoType *Func,
                                llvm::DIFile *Unit, bool decl);
  llvm::DISubroutineType *
  getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
  /// \return debug info descriptor for vtable.
  llvm::DIType *getOrCreateVTablePtrType(llvm::DIFile *F);

  /// \return namespace descriptor for the given namespace decl.
  llvm::DINamespace *getOrCreateNamespace(const NamespaceDecl *N);
  llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty,
                                      QualType PointeeTy, llvm::DIFile *F,
                                      TypeLoc TL = TypeLoc());
  llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache);

  /// A helper function to create a subprogram for a single member
  /// function GlobalDecl.
  llvm::DISubprogram *CreateCXXMemberFunction(const CXXMethodDecl *Method,
                                              llvm::DIFile *F,
                                              llvm::DIType *RecordTy);

  /// A helper function to collect debug info for C++ member
  /// functions. This is used while creating debug info entry for a
  /// Record.
  void CollectCXXMemberFunctions(const CXXRecordDecl *Decl, llvm::DIFile *F,
                                 SmallVectorImpl<llvm::Metadata *> &E,
                                 llvm::DIType *T);

  /// A helper function to collect debug info for C++ base
  /// classes. This is used while creating debug info entry for a
  /// Record.
  void CollectCXXBases(const CXXRecordDecl *Decl, llvm::DIFile *F,
                       SmallVectorImpl<llvm::Metadata *> &EltTys,
                       llvm::DIType *RecordTy);

  /// Helper function for CollectCXXBases.
  /// Adds debug info entries for types in Bases that are not in SeenTypes.
  void CollectCXXBasesAux(
      const CXXRecordDecl *RD, llvm::DIFile *Unit,
      SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
      const CXXRecordDecl::base_class_const_range &Bases,
      llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
      llvm::DINode::DIFlags StartingFlags);

  struct TemplateArgs {
    const TemplateParameterList *TList;
    llvm::ArrayRef<TemplateArgument> Args;
  };
  /// A helper function to collect template parameters.
  llvm::DINodeArray CollectTemplateParams(Optional<TemplateArgs> Args,
                                          llvm::DIFile *Unit);
  /// A helper function to collect debug info for function template
  /// parameters.
  llvm::DINodeArray CollectFunctionTemplateParams(const FunctionDecl *FD,
                                                  llvm::DIFile *Unit);

  /// A helper function to collect debug info for function template
  /// parameters.
  llvm::DINodeArray CollectVarTemplateParams(const VarDecl *VD,
                                             llvm::DIFile *Unit);

  Optional<TemplateArgs> GetTemplateArgs(const VarDecl *) const;
  Optional<TemplateArgs> GetTemplateArgs(const RecordDecl *) const;
  Optional<TemplateArgs> GetTemplateArgs(const FunctionDecl *) const;

  /// A helper function to collect debug info for template
  /// parameters.
  llvm::DINodeArray CollectCXXTemplateParams(const RecordDecl *TS,
                                             llvm::DIFile *F);

  /// A helper function to collect debug info for btf_decl_tag annotations.
  llvm::DINodeArray CollectBTFDeclTagAnnotations(const Decl *D);

  llvm::DIType *createFieldType(StringRef name, QualType type,
                                SourceLocation loc, AccessSpecifier AS,
                                uint64_t offsetInBits, uint32_t AlignInBits,
                                llvm::DIFile *tunit, llvm::DIScope *scope,
                                const RecordDecl *RD = nullptr,
                                llvm::DINodeArray Annotations = nullptr,
                                TypeLoc TL = TypeLoc());

  llvm::DIType *createFieldType(StringRef name, QualType type,
                                SourceLocation loc, AccessSpecifier AS,
                                uint64_t offsetInBits, llvm::DIFile *tunit,
                                llvm::DIScope *scope,
                                const RecordDecl *RD = nullptr) {
    return createFieldType(name, type, loc, AS, offsetInBits, 0, tunit, scope,
                           RD);
  }

  /// Create new bit field member.
  llvm::DIType *createBitFieldType(const FieldDecl *BitFieldDecl,
                                   llvm::DIScope *RecordTy,
                                   const RecordDecl *RD);

  /// Helpers for collecting fields of a record.
  /// @{
  void CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,
                                 SmallVectorImpl<llvm::Metadata *> &E,
                                 llvm::DIType *RecordTy);
  llvm::DIDerivedType *CreateRecordStaticField(const VarDecl *Var,
                                               llvm::DIType *RecordTy,
                                               const RecordDecl *RD);
  void CollectRecordNormalField(const FieldDecl *Field, uint64_t OffsetInBits,
                                llvm::DIFile *F,
                                SmallVectorImpl<llvm::Metadata *> &E,
                                llvm::DIType *RecordTy, const RecordDecl *RD);
  void CollectRecordNestedType(const TypeDecl *RD,
                               SmallVectorImpl<llvm::Metadata *> &E);
  void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile *F,
                           SmallVectorImpl<llvm::Metadata *> &E,
                           llvm::DICompositeType *RecordTy);

  /// If the C++ class has vtable info then insert appropriate debug
  /// info entry in EltTys vector.
  void CollectVTableInfo(const CXXRecordDecl *Decl, llvm::DIFile *F,
                         SmallVectorImpl<llvm::Metadata *> &EltTys);
  /// @}

  /// Create a new lexical block node and push it on the stack.
  void CreateLexicalBlock(SourceLocation Loc);

  /// If target-specific LLVM \p AddressSpace directly maps to target-specific
  /// DWARF address space, appends extended dereferencing mechanism to complex
  /// expression \p Expr. Otherwise, does nothing.
  ///
  /// Extended dereferencing mechanism is has the following format:
  ///     DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
  void AppendAddressSpaceXDeref(unsigned AddressSpace,
                                SmallVectorImpl<int64_t> &Expr) const;

  /// A helper function to collect debug info for the default elements of a
  /// block.
  ///
  /// \returns The next available field offset after the default elements.
  uint64_t collectDefaultElementTypesForBlockPointer(
      const BlockPointerType *Ty, llvm::DIFile *Unit,
      llvm::DIDerivedType *DescTy, unsigned LineNo,
      SmallVectorImpl<llvm::Metadata *> &EltTys);

  /// A helper function to collect debug info for the default fields of a
  /// block.
  void collectDefaultFieldsForBlockLiteralDeclare(
      const CGBlockInfo &Block, const ASTContext &Context, SourceLocation Loc,
      const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
      SmallVectorImpl<llvm::Metadata *> &Fields);

public:
  CGDebugInfo(CodeGenModule &CGM);
  ~CGDebugInfo();

  void finalize();

  /// Remap a given path with the current debug prefix map
  std::string remapDIPath(StringRef) const;

  /// Register VLA size expression debug node with the qualified type.
  void registerVLASizeExpression(QualType Ty, llvm::Metadata *SizeExpr) {
    SizeExprCache[Ty] = SizeExpr;
  }

  /// Module debugging: Support for building PCMs.
  /// @{
  /// Set the main CU's DwoId field to \p Signature.
  void setDwoId(uint64_t Signature);

  /// When generating debug information for a clang module or
  /// precompiled header, this module map will be used to determine
  /// the module of origin of each Decl.
  void setModuleMap(ModuleMap &MMap) { ClangModuleMap = &MMap; }

  /// When generating debug information for a clang module or
  /// precompiled header, this module map will be used to determine
  /// the module of origin of each Decl.
  void setPCHDescriptor(ASTSourceDescriptor PCH) { PCHDescriptor = PCH; }
  /// @}

  /// Update the current source location. If \arg loc is invalid it is
  /// ignored.
  void setLocation(SourceLocation Loc);

  /// Return the current source location. This does not necessarily correspond
  /// to the IRBuilder's current DebugLoc.
  SourceLocation getLocation() const { return CurLoc; }

  /// Update the current inline scope. All subsequent calls to \p EmitLocation
  /// will create a location with this inlinedAt field.
  void setInlinedAt(llvm::MDNode *InlinedAt) { CurInlinedAt = InlinedAt; }

  /// \return the current inline scope.
  llvm::MDNode *getInlinedAt() const { return CurInlinedAt; }

  // Converts a SourceLocation to a DebugLoc
  llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc);

  /// Emit metadata to indicate a change in line/column information in
  /// the source file. If the location is invalid, the previous
  /// location will be reused.
  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);

  QualType getFunctionType(const FunctionDecl *FD, QualType RetTy,
                           const SmallVectorImpl<const VarDecl *> &Args);

  /// Emit a call to llvm.dbg.function.start to indicate
  /// start of a new function.
  /// \param Loc       The location of the function header.
  /// \param ScopeLoc  The location of the function body.
  void emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
                         SourceLocation ScopeLoc, QualType FnType,
                         llvm::Function *Fn, bool CurFnIsThunk);

  /// Start a new scope for an inlined function.
  void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD);
  /// End an inlined function scope.
  void EmitInlineFunctionEnd(CGBuilderTy &Builder);

  /// Emit debug info for a function declaration.
  /// \p Fn is set only when a declaration for a debug call site gets created.
  void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
                        QualType FnType, llvm::Function *Fn = nullptr);

  /// Emit debug info for an extern function being called.
  /// This is needed for call site debug info.
  void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
                               QualType CalleeType,
                               const FunctionDecl *CalleeDecl);

  /// Constructs the debug code for exiting a function.
  void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn);

  /// Emit metadata to indicate the beginning of a new lexical block
  /// and push the block onto the stack.
  void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc);

  /// Emit metadata to indicate the end of a new lexical block and pop
  /// the current block.
  void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc);

  /// Emit call to \c llvm.dbg.declare for an automatic variable
  /// declaration.
  /// Returns a pointer to the DILocalVariable associated with the
  /// llvm.dbg.declare, or nullptr otherwise.
  llvm::DILocalVariable *
  EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
                            CGBuilderTy &Builder,
                            const bool UsePointerValue = false);

  /// Emit call to \c llvm.dbg.label for an label.
  void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder);

  /// Emit call to \c llvm.dbg.declare for an imported variable
  /// declaration in a block.
  void EmitDeclareOfBlockDeclRefVariable(
      const VarDecl *variable, llvm::Value *storage, CGBuilderTy &Builder,
      const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint = nullptr);

  /// Emit call to \c llvm.dbg.declare for an argument variable
  /// declaration.
  llvm::DILocalVariable *EmitDeclareOfArgVariable(const VarDecl *Decl,
                                                  llvm::Value *AI,
                                                  unsigned ArgNo,
                                                  CGBuilderTy &Builder);

  /// Emit call to \c llvm.dbg.declare for the block-literal argument
  /// to a block invocation function.
  void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
                                            StringRef Name, unsigned ArgNo,
                                            llvm::AllocaInst *LocalAddr,
                                            CGBuilderTy &Builder);

  /// Emit information about a global variable.
  void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);

  /// Emit a constant global variable's debug info.
  void EmitGlobalVariable(const ValueDecl *VD, const APValue &Init);

  /// Emit information about an external variable.
  void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);

  /// Emit C++ using directive.
  void EmitUsingDirective(const UsingDirectiveDecl &UD);

  /// Emit the type explicitly casted to.
  void EmitExplicitCastType(QualType Ty);

  /// Emit the type even if it might not be used.
  void EmitAndRetainType(QualType Ty);

  /// Emit a shadow decl brought in by a using or using-enum
  void EmitUsingShadowDecl(const UsingShadowDecl &USD);

  /// Emit C++ using declaration.
  void EmitUsingDecl(const UsingDecl &UD);

  /// Emit C++ using-enum declaration.
  void EmitUsingEnumDecl(const UsingEnumDecl &UD);

  /// Emit an @import declaration.
  void EmitImportDecl(const ImportDecl &ID);

  /// Emit C++ namespace alias.
  llvm::DIImportedEntity *EmitNamespaceAlias(const NamespaceAliasDecl &NA);

  /// Emit record type's standalone debug info.
  llvm::DIType *getOrCreateRecordType(QualType Ty, SourceLocation L);

  /// Emit an Objective-C interface type standalone debug info.
  llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc);

  /// Emit standalone debug info for a type.
  llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc);

  /// Add heapallocsite metadata for MSAllocator calls.
  void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy,
                                SourceLocation Loc);

  void completeType(const EnumDecl *ED);
  void completeType(const RecordDecl *RD);
  void completeRequiredType(const RecordDecl *RD);
  void completeClassData(const RecordDecl *RD);
  void completeClass(const RecordDecl *RD);

  void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
  void completeUnusedClass(const CXXRecordDecl &D);

  /// Create debug info for a macro defined by a #define directive or a macro
  /// undefined by a #undef directive.
  llvm::DIMacro *CreateMacro(llvm::DIMacroFile *Parent, unsigned MType,
                             SourceLocation LineLoc, StringRef Name,
                             StringRef Value);

  /// Create debug info for a file referenced by an #include directive.
  llvm::DIMacroFile *CreateTempMacroFile(llvm::DIMacroFile *Parent,
                                         SourceLocation LineLoc,
                                         SourceLocation FileLoc);

  Param2DILocTy &getParamDbgMappings() { return ParamDbgMappings; }
  ParamDecl2StmtTy &getCoroutineParameterMappings() {
    return CoroutineParameterMappings;
  }

private:
  /// Emit call to llvm.dbg.declare for a variable declaration.
  /// Returns a pointer to the DILocalVariable associated with the
  /// llvm.dbg.declare, or nullptr otherwise.
  llvm::DILocalVariable *EmitDeclare(const VarDecl *decl, llvm::Value *AI,
                                     llvm::Optional<unsigned> ArgNo,
                                     CGBuilderTy &Builder,
                                     const bool UsePointerValue = false);

  struct BlockByRefType {
    /// The wrapper struct used inside the __block_literal struct.
    llvm::DIType *BlockByRefWrapper;
    /// The type as it appears in the source code.
    llvm::DIType *WrappedType;
  };

  std::string GetName(const Decl*, bool Qualified = false) const;

  /// Build up structure info for the byref.  See \a BuildByRefType.
  BlockByRefType EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
                                              uint64_t *OffSet);

  /// Get context info for the DeclContext of \p Decl.
  llvm::DIScope *getDeclContextDescriptor(const Decl *D);
  /// Get context info for a given DeclContext \p Decl.
  llvm::DIScope *getContextDescriptor(const Decl *Context,
                                      llvm::DIScope *Default);

  llvm::DIScope *getCurrentContextDescriptor(const Decl *Decl);

  /// Create a forward decl for a RecordType in a given context.
  llvm::DICompositeType *getOrCreateRecordFwdDecl(const RecordType *,
                                                  llvm::DIScope *);

  /// Return current directory name.
  StringRef getCurrentDirname();

  /// Create new compile unit.
  void CreateCompileUnit();

  /// Compute the file checksum debug info for input file ID.
  Optional<llvm::DIFile::ChecksumKind>
  computeChecksum(FileID FID, SmallString<32> &Checksum) const;

  /// Get the source of the given file ID.
  Optional<StringRef> getSource(const SourceManager &SM, FileID FID);

  /// Convenience function to get the file debug info descriptor for the input
  /// location.
  llvm::DIFile *getOrCreateFile(SourceLocation Loc);

  /// Create a file debug info descriptor for a source file.
  llvm::DIFile *
  createFile(StringRef FileName,
             Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
             Optional<StringRef> Source);

  /// Get the type from the cache or create a new type if necessary.
  llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg,
                                TypeLoc TL = TypeLoc());

  /// Get a reference to a clang module.  If \p CreateSkeletonCU is true,
  /// this also creates a split dwarf skeleton compile unit.
  llvm::DIModule *getOrCreateModuleRef(ASTSourceDescriptor Mod,
                                       bool CreateSkeletonCU);

  /// DebugTypeExtRefs: If \p D originated in a clang module, return it.
  llvm::DIModule *getParentModuleOrNull(const Decl *D);

  /// Get the type from the cache or create a new partial type if
  /// necessary.
  llvm::DICompositeType *getOrCreateLimitedType(const RecordType *Ty);

  /// Create type metadata for a source language type.
  llvm::DIType *CreateTypeNode(QualType Ty, llvm::DIFile *Fg,
                               TypeLoc TL = TypeLoc());

  /// Create new member and increase Offset by FType's size.
  llvm::DIType *CreateMemberType(llvm::DIFile *Unit, QualType FType,
                                 StringRef Name, uint64_t *Offset);

  /// Retrieve the DIDescriptor, if any, for the canonical form of this
  /// declaration.
  llvm::DINode *getDeclarationOrDefinition(const Decl *D);

  /// \return debug info descriptor to describe method
  /// declaration for the given method definition.
  llvm::DISubprogram *getFunctionDeclaration(const Decl *D);

  /// \return          debug info descriptor to the describe method declaration
  ///                  for the given method definition.
  /// \param FnType    For Objective-C methods, their type.
  /// \param LineNo    The declaration's line number.
  /// \param Flags     The DIFlags for the method declaration.
  /// \param SPFlags   The subprogram-spcific flags for the method declaration.
  llvm::DISubprogram *
  getObjCMethodDeclaration(const Decl *D, llvm::DISubroutineType *FnType,
                           unsigned LineNo, llvm::DINode::DIFlags Flags,
                           llvm::DISubprogram::DISPFlags SPFlags);

  /// \return debug info descriptor to describe in-class static data
  /// member declaration for the given out-of-class definition.  If D
  /// is an out-of-class definition of a static data member of a
  /// class, find its corresponding in-class declaration.
  llvm::DIDerivedType *
  getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);

  /// Helper that either creates a forward declaration or a stub.
  llvm::DISubprogram *getFunctionFwdDeclOrStub(GlobalDecl GD, bool Stub);

  /// Create a subprogram describing the forward declaration
  /// represented in the given FunctionDecl wrapped in a GlobalDecl.
  llvm::DISubprogram *getFunctionForwardDeclaration(GlobalDecl GD);

  /// Create a DISubprogram describing the function
  /// represented in the given FunctionDecl wrapped in a GlobalDecl.
  llvm::DISubprogram *getFunctionStub(GlobalDecl GD);

  /// Create a global variable describing the forward declaration
  /// represented in the given VarDecl.
  llvm::DIGlobalVariable *
  getGlobalVariableForwardDeclaration(const VarDecl *VD);

  /// Return a global variable that represents one of the collection of global
  /// variables created for an anonmyous union.
  ///
  /// Recursively collect all of the member fields of a global
  /// anonymous decl and create static variables for them. The first
  /// time this is called it needs to be on a union and then from
  /// there we can have additional unnamed fields.
  llvm::DIGlobalVariableExpression *
  CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile *Unit,
                         unsigned LineNo, StringRef LinkageName,
                         llvm::GlobalVariable *Var, llvm::DIScope *DContext);


  /// Return flags which enable debug info emission for call sites, provided
  /// that it is supported and enabled.
  llvm::DINode::DIFlags getCallSiteRelatedAttrs() const;

  /// Get the printing policy for producing names for debug info.
  PrintingPolicy getPrintingPolicy() const;

  /// Get function name for the given FunctionDecl. If the name is
  /// constructed on demand (e.g., C++ destructor) then the name is
  /// stored on the side.
  StringRef getFunctionName(const FunctionDecl *FD);

  /// Returns the unmangled name of an Objective-C method.
  /// This is the display name for the debugging info.
  StringRef getObjCMethodName(const ObjCMethodDecl *FD);

  /// Return selector name. This is used for debugging
  /// info.
  StringRef getSelectorName(Selector S);

  /// Get class name including template argument list.
  StringRef getClassName(const RecordDecl *RD);

  /// Get the vtable name for the given class.
  StringRef getVTableName(const CXXRecordDecl *Decl);

  /// Get the name to use in the debug info for a dynamic initializer or atexit
  /// stub function.
  StringRef getDynamicInitializerName(const VarDecl *VD,
                                      DynamicInitKind StubKind,
                                      llvm::Function *InitFn);

  /// Get line number for the location. If location is invalid
  /// then use current location.
  unsigned getLineNumber(SourceLocation Loc);

  /// Get column number for the location. If location is
  /// invalid then use current location.
  /// \param Force  Assume DebugColumnInfo option is true.
  unsigned getColumnNumber(SourceLocation Loc, bool Force = false);

  /// Collect various properties of a FunctionDecl.
  /// \param GD  A GlobalDecl whose getDecl() must return a FunctionDecl.
  void collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
                                StringRef &Name, StringRef &LinkageName,
                                llvm::DIScope *&FDContext,
                                llvm::DINodeArray &TParamsArray,
                                llvm::DINode::DIFlags &Flags);

  /// Collect various properties of a VarDecl.
  void collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit,
                           unsigned &LineNo, QualType &T, StringRef &Name,
                           StringRef &LinkageName,
                           llvm::MDTuple *&TemplateParameters,
                           llvm::DIScope *&VDContext);

  /// Allocate a copy of \p A using the DebugInfoNames allocator
  /// and return a reference to it. If multiple arguments are given the strings
  /// are concatenated.
  StringRef internString(StringRef A, StringRef B = StringRef()) {
    char *Data = DebugInfoNames.Allocate<char>(A.size() + B.size());
    if (!A.empty())
      std::memcpy(Data, A.data(), A.size());
    if (!B.empty())
      std::memcpy(Data + A.size(), B.data(), B.size());
    return StringRef(Data, A.size() + B.size());
  }
};

/// A scoped helper to set the current debug location to the specified
/// location or preferred location of the specified Expr.
class ApplyDebugLocation {
private:
  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false);
  ApplyDebugLocation(CodeGenFunction &CGF, bool DefaultToEmpty,
                     SourceLocation TemporaryLocation);

  llvm::DebugLoc OriginalLocation;
  CodeGenFunction *CGF;

public:
  /// Set the location to the (valid) TemporaryLocation.
  ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation);
  ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E);
  ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc);
  ApplyDebugLocation(ApplyDebugLocation &&Other) : CGF(Other.CGF) {
    Other.CGF = nullptr;
  }
  ApplyDebugLocation &operator=(ApplyDebugLocation &&) = default;

  ~ApplyDebugLocation();

  /// Apply TemporaryLocation if it is valid. Otherwise switch
  /// to an artificial debug location that has a valid scope, but no
  /// line information.
  ///
  /// Artificial locations are useful when emitting compiler-generated
  /// helper functions that have no source location associated with
  /// them. The DWARF specification allows the compiler to use the
  /// special line number 0 to indicate code that can not be
  /// attributed to any source location. Note that passing an empty
  /// SourceLocation to CGDebugInfo::setLocation() will result in the
  /// last valid location being reused.
  static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF) {
    return ApplyDebugLocation(CGF, false, SourceLocation());
  }
  /// Apply TemporaryLocation if it is valid. Otherwise switch
  /// to an artificial debug location that has a valid scope, but no
  /// line information.
  static ApplyDebugLocation
  CreateDefaultArtificial(CodeGenFunction &CGF,
                          SourceLocation TemporaryLocation) {
    return ApplyDebugLocation(CGF, false, TemporaryLocation);
  }

  /// Set the IRBuilder to not attach debug locations.  Note that
  /// passing an empty SourceLocation to \a CGDebugInfo::setLocation()
  /// will result in the last valid location being reused.  Note that
  /// all instructions that do not have a location at the beginning of
  /// a function are counted towards to function prologue.
  static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF) {
    return ApplyDebugLocation(CGF, true, SourceLocation());
  }
};

/// A scoped helper to set the current debug location to an inlined location.
class ApplyInlineDebugLocation {
  SourceLocation SavedLocation;
  CodeGenFunction *CGF;

public:
  /// Set up the CodeGenFunction's DebugInfo to produce inline locations for the
  /// function \p InlinedFn. The current debug location becomes the inlined call
  /// site of the inlined function.
  ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn);
  /// Restore everything back to the original state.
  ~ApplyInlineDebugLocation();
};

} // namespace CodeGen
} // namespace clang

#endif // LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H
