//===-- Statistics.cpp - Debug Info quality metrics -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm-dwarfdump.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/JSON.h"

#define DEBUG_TYPE "dwarfdump"
using namespace llvm;
using namespace llvm::dwarfdump;
using namespace llvm::object;

namespace {
/// This represents the number of categories of debug location coverage being
/// calculated. The first category is the number of variables with 0% location
/// coverage, but the last category is the number of variables with 100%
/// location coverage.
constexpr int NumOfCoverageCategories = 12;

/// This is used for zero location coverage bucket.
constexpr unsigned ZeroCoverageBucket = 0;

/// The UINT64_MAX is used as an indication of the overflow.
constexpr uint64_t OverflowValue = std::numeric_limits<uint64_t>::max();

/// This represents variables DIE offsets.
using AbstractOriginVarsTy = llvm::SmallVector<uint64_t>;
/// This maps function DIE offset to its variables.
using AbstractOriginVarsTyMap = llvm::DenseMap<uint64_t, AbstractOriginVarsTy>;
/// This represents function DIE offsets containing an abstract_origin.
using FunctionsWithAbstractOriginTy = llvm::SmallVector<uint64_t>;

/// This represents a data type for the stats and it helps us to
/// detect an overflow.
/// NOTE: This can be implemented as a template if there is an another type
/// needing this.
struct SaturatingUINT64 {
  /// Number that represents the stats.
  uint64_t Value;

  SaturatingUINT64(uint64_t Value_) : Value(Value_) {}

  void operator++(int) { return *this += 1; }
  void operator+=(uint64_t Value_) {
    if (Value != OverflowValue) {
      if (Value < OverflowValue - Value_)
        Value += Value_;
      else
        Value = OverflowValue;
    }
  }
};

/// Utility struct to store the full location of a DIE - its CU and offset.
struct DIELocation {
  DWARFUnit *DwUnit;
  uint64_t DIEOffset;
  DIELocation(DWARFUnit *_DwUnit, uint64_t _DIEOffset)
      : DwUnit(_DwUnit), DIEOffset(_DIEOffset) {}
};
/// This represents DWARF locations of CrossCU referencing DIEs.
using CrossCUReferencingDIELocationTy = llvm::SmallVector<DIELocation>;

/// This maps function DIE offset to its DWARF CU.
using FunctionDIECUTyMap = llvm::DenseMap<uint64_t, DWARFUnit *>;

/// Holds statistics for one function (or other entity that has a PC range and
/// contains variables, such as a compile unit).
struct PerFunctionStats {
  /// Number of inlined instances of this function.
  uint64_t NumFnInlined = 0;
  /// Number of out-of-line instances of this function.
  uint64_t NumFnOutOfLine = 0;
  /// Number of inlined instances that have abstract origins.
  uint64_t NumAbstractOrigins = 0;
  /// Number of variables and parameters with location across all inlined
  /// instances.
  uint64_t TotalVarWithLoc = 0;
  /// Number of constants with location across all inlined instances.
  uint64_t ConstantMembers = 0;
  /// Number of arificial variables, parameters or members across all instances.
  uint64_t NumArtificial = 0;
  /// List of all Variables and parameters in this function.
  StringSet<> VarsInFunction;
  /// Compile units also cover a PC range, but have this flag set to false.
  bool IsFunction = false;
  /// Function has source location information.
  bool HasSourceLocation = false;
  /// Number of function parameters.
  uint64_t NumParams = 0;
  /// Number of function parameters with source location.
  uint64_t NumParamSourceLocations = 0;
  /// Number of function parameters with type.
  uint64_t NumParamTypes = 0;
  /// Number of function parameters with a DW_AT_location.
  uint64_t NumParamLocations = 0;
  /// Number of local variables.
  uint64_t NumLocalVars = 0;
  /// Number of local variables with source location.
  uint64_t NumLocalVarSourceLocations = 0;
  /// Number of local variables with type.
  uint64_t NumLocalVarTypes = 0;
  /// Number of local variables with DW_AT_location.
  uint64_t NumLocalVarLocations = 0;
};

/// Holds accumulated global statistics about DIEs.
struct GlobalStats {
  /// Total number of PC range bytes covered by DW_AT_locations.
  SaturatingUINT64 TotalBytesCovered = 0;
  /// Total number of parent DIE PC range bytes covered by DW_AT_Locations.
  SaturatingUINT64 ScopeBytesCovered = 0;
  /// Total number of PC range bytes in each variable's enclosing scope.
  SaturatingUINT64 ScopeBytes = 0;
  /// Total number of PC range bytes covered by DW_AT_locations with
  /// the debug entry values (DW_OP_entry_value).
  SaturatingUINT64 ScopeEntryValueBytesCovered = 0;
  /// Total number of PC range bytes covered by DW_AT_locations of
  /// formal parameters.
  SaturatingUINT64 ParamScopeBytesCovered = 0;
  /// Total number of PC range bytes in each parameter's enclosing scope.
  SaturatingUINT64 ParamScopeBytes = 0;
  /// Total number of PC range bytes covered by DW_AT_locations with
  /// the debug entry values (DW_OP_entry_value) (only for parameters).
  SaturatingUINT64 ParamScopeEntryValueBytesCovered = 0;
  /// Total number of PC range bytes covered by DW_AT_locations (only for local
  /// variables).
  SaturatingUINT64 LocalVarScopeBytesCovered = 0;
  /// Total number of PC range bytes in each local variable's enclosing scope.
  SaturatingUINT64 LocalVarScopeBytes = 0;
  /// Total number of PC range bytes covered by DW_AT_locations with
  /// the debug entry values (DW_OP_entry_value) (only for local variables).
  SaturatingUINT64 LocalVarScopeEntryValueBytesCovered = 0;
  /// Total number of call site entries (DW_AT_call_file & DW_AT_call_line).
  SaturatingUINT64 CallSiteEntries = 0;
  /// Total number of call site DIEs (DW_TAG_call_site).
  SaturatingUINT64 CallSiteDIEs = 0;
  /// Total number of call site parameter DIEs (DW_TAG_call_site_parameter).
  SaturatingUINT64 CallSiteParamDIEs = 0;
  /// Total byte size of concrete functions. This byte size includes
  /// inline functions contained in the concrete functions.
  SaturatingUINT64 FunctionSize = 0;
  /// Total byte size of inlined functions. This is the total number of bytes
  /// for the top inline functions within concrete functions. This can help
  /// tune the inline settings when compiling to match user expectations.
  SaturatingUINT64 InlineFunctionSize = 0;
};

/// Holds accumulated debug location statistics about local variables and
/// formal parameters.
struct LocationStats {
  /// Map the scope coverage decile to the number of variables in the decile.
  /// The first element of the array (at the index zero) represents the number
  /// of variables with the no debug location at all, but the last element
  /// in the vector represents the number of fully covered variables within
  /// its scope.
  std::vector<SaturatingUINT64> VarParamLocStats{
      std::vector<SaturatingUINT64>(NumOfCoverageCategories, 0)};
  /// Map non debug entry values coverage.
  std::vector<SaturatingUINT64> VarParamNonEntryValLocStats{
      std::vector<SaturatingUINT64>(NumOfCoverageCategories, 0)};
  /// The debug location statistics for formal parameters.
  std::vector<SaturatingUINT64> ParamLocStats{
      std::vector<SaturatingUINT64>(NumOfCoverageCategories, 0)};
  /// Map non debug entry values coverage for formal parameters.
  std::vector<SaturatingUINT64> ParamNonEntryValLocStats{
      std::vector<SaturatingUINT64>(NumOfCoverageCategories, 0)};
  /// The debug location statistics for local variables.
  std::vector<SaturatingUINT64> LocalVarLocStats{
      std::vector<SaturatingUINT64>(NumOfCoverageCategories, 0)};
  /// Map non debug entry values coverage for local variables.
  std::vector<SaturatingUINT64> LocalVarNonEntryValLocStats{
      std::vector<SaturatingUINT64>(NumOfCoverageCategories, 0)};
  /// Total number of local variables and function parameters processed.
  SaturatingUINT64 NumVarParam = 0;
  /// Total number of formal parameters processed.
  SaturatingUINT64 NumParam = 0;
  /// Total number of local variables processed.
  SaturatingUINT64 NumVar = 0;
};

/// Holds accumulated debug line statistics across all CUs.
struct LineStats {
  SaturatingUINT64 NumBytes = 0;
  SaturatingUINT64 NumLineZeroBytes = 0;
  SaturatingUINT64 NumEntries = 0;
  SaturatingUINT64 NumIsStmtEntries = 0;
  SaturatingUINT64 NumUniqueEntries = 0;
  SaturatingUINT64 NumUniqueNonZeroEntries = 0;
};
} // namespace

/// Collect debug location statistics for one DIE.
static void collectLocStats(uint64_t ScopeBytesCovered, uint64_t BytesInScope,
                            std::vector<SaturatingUINT64> &VarParamLocStats,
                            std::vector<SaturatingUINT64> &ParamLocStats,
                            std::vector<SaturatingUINT64> &LocalVarLocStats,
                            bool IsParam, bool IsLocalVar) {
  auto getCoverageBucket = [ScopeBytesCovered, BytesInScope]() -> unsigned {
    // No debug location at all for the variable.
    if (ScopeBytesCovered == 0)
      return 0;
    // Fully covered variable within its scope.
    if (ScopeBytesCovered >= BytesInScope)
      return NumOfCoverageCategories - 1;
    // Get covered range (e.g. 20%-29%).
    unsigned LocBucket = 100 * (double)ScopeBytesCovered / BytesInScope;
    LocBucket /= 10;
    return LocBucket + 1;
  };

  unsigned CoverageBucket = getCoverageBucket();

  VarParamLocStats[CoverageBucket].Value++;
  if (IsParam)
    ParamLocStats[CoverageBucket].Value++;
  else if (IsLocalVar)
    LocalVarLocStats[CoverageBucket].Value++;
}

/// Construct an identifier for a given DIE from its Prefix, Name, DeclFileName
/// and DeclLine. The identifier aims to be unique for any unique entities,
/// but keeping the same among different instances of the same entity.
static std::string constructDieID(DWARFDie Die,
                                  StringRef Prefix = StringRef()) {
  std::string IDStr;
  llvm::raw_string_ostream ID(IDStr);
  ID << Prefix
     << Die.getName(DINameKind::LinkageName);

  // Prefix + Name is enough for local variables and parameters.
  if (!Prefix.empty() && Prefix != "g")
    return IDStr;

  auto DeclFile = Die.findRecursively(dwarf::DW_AT_decl_file);
  std::string File;
  if (DeclFile) {
    DWARFUnit *U = Die.getDwarfUnit();
    if (const auto *LT = U->getContext().getLineTableForUnit(U))
      if (LT->getFileNameByIndex(
              dwarf::toUnsigned(DeclFile, 0), U->getCompilationDir(),
              DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File))
        File = std::string(sys::path::filename(File));
  }
  ID << ":" << (File.empty() ? "/" : File);
  ID << ":"
     << dwarf::toUnsigned(Die.findRecursively(dwarf::DW_AT_decl_line), 0);
  return IDStr;
}

/// Return the number of bytes in the overlap of ranges A and B.
static uint64_t calculateOverlap(DWARFAddressRange A, DWARFAddressRange B) {
  uint64_t Lower = std::max(A.LowPC, B.LowPC);
  uint64_t Upper = std::min(A.HighPC, B.HighPC);
  if (Lower >= Upper)
    return 0;
  return Upper - Lower;
}

/// Collect debug info quality metrics for one DIE.
static void collectStatsForDie(DWARFDie Die, const std::string &FnPrefix,
                               const std::string &VarPrefix,
                               uint64_t BytesInScope, uint32_t InlineDepth,
                               StringMap<PerFunctionStats> &FnStatMap,
                               GlobalStats &GlobalStats,
                               LocationStats &LocStats,
                               AbstractOriginVarsTy *AbstractOriginVariables) {
  const dwarf::Tag Tag = Die.getTag();
  // Skip CU node.
  if (Tag == dwarf::DW_TAG_compile_unit)
    return;

  bool HasLoc = false;
  bool HasSrcLoc = false;
  bool HasType = false;
  uint64_t TotalBytesCovered = 0;
  uint64_t ScopeBytesCovered = 0;
  uint64_t BytesEntryValuesCovered = 0;
  auto &FnStats = FnStatMap[FnPrefix];
  bool IsParam = Tag == dwarf::DW_TAG_formal_parameter;
  bool IsLocalVar = Tag == dwarf::DW_TAG_variable;
  bool IsConstantMember = Tag == dwarf::DW_TAG_member &&
                          Die.find(dwarf::DW_AT_const_value);

  // For zero covered inlined variables the locstats will be
  // calculated later.
  bool DeferLocStats = false;

  if (Tag == dwarf::DW_TAG_call_site || Tag == dwarf::DW_TAG_GNU_call_site) {
    GlobalStats.CallSiteDIEs++;
    return;
  }

  if (Tag == dwarf::DW_TAG_call_site_parameter ||
      Tag == dwarf::DW_TAG_GNU_call_site_parameter) {
    GlobalStats.CallSiteParamDIEs++;
    return;
  }

  if (!IsParam && !IsLocalVar && !IsConstantMember) {
    // Not a variable or constant member.
    return;
  }

  // Ignore declarations of global variables.
  if (IsLocalVar && Die.find(dwarf::DW_AT_declaration))
    return;

  if (Die.findRecursively(dwarf::DW_AT_decl_file) &&
      Die.findRecursively(dwarf::DW_AT_decl_line))
    HasSrcLoc = true;

  if (Die.findRecursively(dwarf::DW_AT_type))
    HasType = true;

  if (Die.find(dwarf::DW_AT_abstract_origin)) {
    if (Die.find(dwarf::DW_AT_location) || Die.find(dwarf::DW_AT_const_value)) {
      if (AbstractOriginVariables) {
        auto Offset = Die.find(dwarf::DW_AT_abstract_origin);
        // Do not track this variable any more, since it has location
        // coverage.
        llvm::erase(*AbstractOriginVariables, (*Offset).getRawUValue());
      }
    } else {
      // The locstats will be handled at the end of
      // the collectStatsRecursive().
      DeferLocStats = true;
    }
  }

  auto IsEntryValue = [&](ArrayRef<uint8_t> D) -> bool {
    DWARFUnit *U = Die.getDwarfUnit();
    DataExtractor Data(toStringRef(D),
                       Die.getDwarfUnit()->getContext().isLittleEndian(), 0);
    DWARFExpression Expression(Data, U->getAddressByteSize(),
                               U->getFormParams().Format);
    // Consider the expression containing the DW_OP_entry_value as
    // an entry value.
    return llvm::any_of(Expression, [](const DWARFExpression::Operation &Op) {
      return Op.getCode() == dwarf::DW_OP_entry_value ||
             Op.getCode() == dwarf::DW_OP_GNU_entry_value;
    });
  };

  if (Die.find(dwarf::DW_AT_const_value)) {
    // This catches constant members *and* variables.
    HasLoc = true;
    ScopeBytesCovered = BytesInScope;
    TotalBytesCovered = BytesInScope;
  } else {
    // Handle variables and function arguments.
    Expected<std::vector<DWARFLocationExpression>> Loc =
        Die.getLocations(dwarf::DW_AT_location);
    if (!Loc) {
      consumeError(Loc.takeError());
    } else {
      HasLoc = true;
      // Get PC coverage.
      auto Default = find_if(
          *Loc, [](const DWARFLocationExpression &L) { return !L.Range; });
      if (Default != Loc->end()) {
        // Assume the entire range is covered by a single location.
        ScopeBytesCovered = BytesInScope;
        TotalBytesCovered = BytesInScope;
      } else {
        // Caller checks this Expected result already, it cannot fail.
        auto ScopeRanges = cantFail(Die.getParent().getAddressRanges());
        for (auto Entry : *Loc) {
          TotalBytesCovered += Entry.Range->HighPC - Entry.Range->LowPC;
          uint64_t ScopeBytesCoveredByEntry = 0;
          // Calculate how many bytes of the parent scope this entry covers.
          // FIXME: In section 2.6.2 of the DWARFv5 spec it says that "The
          // address ranges defined by the bounded location descriptions of a
          // location list may overlap". So in theory a variable can have
          // multiple simultaneous locations, which would make this calculation
          // misleading because we will count the overlapped areas
          // twice. However, clang does not currently emit DWARF like this.
          for (DWARFAddressRange R : ScopeRanges) {
            ScopeBytesCoveredByEntry += calculateOverlap(*Entry.Range, R);
          }
          ScopeBytesCovered += ScopeBytesCoveredByEntry;
          if (IsEntryValue(Entry.Expr))
            BytesEntryValuesCovered += ScopeBytesCoveredByEntry;
        }
      }
    }
  }

  // Calculate the debug location statistics.
  if (BytesInScope && !DeferLocStats) {
    LocStats.NumVarParam.Value++;
    if (IsParam)
      LocStats.NumParam.Value++;
    else if (IsLocalVar)
      LocStats.NumVar.Value++;

    collectLocStats(ScopeBytesCovered, BytesInScope, LocStats.VarParamLocStats,
                    LocStats.ParamLocStats, LocStats.LocalVarLocStats, IsParam,
                    IsLocalVar);
    // Non debug entry values coverage statistics.
    collectLocStats(ScopeBytesCovered - BytesEntryValuesCovered, BytesInScope,
                    LocStats.VarParamNonEntryValLocStats,
                    LocStats.ParamNonEntryValLocStats,
                    LocStats.LocalVarNonEntryValLocStats, IsParam, IsLocalVar);
  }

  // Collect PC range coverage data.
  if (DWARFDie D =
          Die.getAttributeValueAsReferencedDie(dwarf::DW_AT_abstract_origin))
    Die = D;

  std::string VarID = constructDieID(Die, VarPrefix);
  FnStats.VarsInFunction.insert(VarID);

  GlobalStats.TotalBytesCovered += TotalBytesCovered;
  if (BytesInScope) {
    GlobalStats.ScopeBytesCovered += ScopeBytesCovered;
    GlobalStats.ScopeBytes += BytesInScope;
    GlobalStats.ScopeEntryValueBytesCovered += BytesEntryValuesCovered;
    if (IsParam) {
      GlobalStats.ParamScopeBytesCovered += ScopeBytesCovered;
      GlobalStats.ParamScopeBytes += BytesInScope;
      GlobalStats.ParamScopeEntryValueBytesCovered += BytesEntryValuesCovered;
    } else if (IsLocalVar) {
      GlobalStats.LocalVarScopeBytesCovered += ScopeBytesCovered;
      GlobalStats.LocalVarScopeBytes += BytesInScope;
      GlobalStats.LocalVarScopeEntryValueBytesCovered +=
          BytesEntryValuesCovered;
    }
    assert(GlobalStats.ScopeBytesCovered.Value <= GlobalStats.ScopeBytes.Value);
  }

  if (IsConstantMember) {
    FnStats.ConstantMembers++;
    return;
  }

  FnStats.TotalVarWithLoc += (unsigned)HasLoc;

  if (Die.find(dwarf::DW_AT_artificial)) {
    FnStats.NumArtificial++;
    return;
  }

  if (IsParam) {
    FnStats.NumParams++;
    if (HasType)
      FnStats.NumParamTypes++;
    if (HasSrcLoc)
      FnStats.NumParamSourceLocations++;
    if (HasLoc)
      FnStats.NumParamLocations++;
  } else if (IsLocalVar) {
    FnStats.NumLocalVars++;
    if (HasType)
      FnStats.NumLocalVarTypes++;
    if (HasSrcLoc)
      FnStats.NumLocalVarSourceLocations++;
    if (HasLoc)
      FnStats.NumLocalVarLocations++;
  }
}

/// Recursively collect variables from subprogram with DW_AT_inline attribute.
static void collectAbstractOriginFnInfo(
    DWARFDie Die, uint64_t SPOffset,
    AbstractOriginVarsTyMap &GlobalAbstractOriginFnInfo,
    AbstractOriginVarsTyMap &LocalAbstractOriginFnInfo) {
  DWARFDie Child = Die.getFirstChild();
  while (Child) {
    const dwarf::Tag ChildTag = Child.getTag();
    if (ChildTag == dwarf::DW_TAG_formal_parameter ||
        ChildTag == dwarf::DW_TAG_variable) {
      GlobalAbstractOriginFnInfo[SPOffset].push_back(Child.getOffset());
      LocalAbstractOriginFnInfo[SPOffset].push_back(Child.getOffset());
    } else if (ChildTag == dwarf::DW_TAG_lexical_block)
      collectAbstractOriginFnInfo(Child, SPOffset, GlobalAbstractOriginFnInfo,
                                  LocalAbstractOriginFnInfo);
    Child = Child.getSibling();
  }
}

/// Recursively collect debug info quality metrics.
static void collectStatsRecursive(
    DWARFDie Die, std::string FnPrefix, std::string VarPrefix,
    uint64_t BytesInScope, uint32_t InlineDepth,
    StringMap<PerFunctionStats> &FnStatMap, GlobalStats &GlobalStats,
    LocationStats &LocStats, FunctionDIECUTyMap &AbstractOriginFnCUs,
    AbstractOriginVarsTyMap &GlobalAbstractOriginFnInfo,
    AbstractOriginVarsTyMap &LocalAbstractOriginFnInfo,
    FunctionsWithAbstractOriginTy &FnsWithAbstractOriginToBeProcessed,
    AbstractOriginVarsTy *AbstractOriginVarsPtr = nullptr) {
  // Skip NULL nodes.
  if (Die.isNULL())
    return;

  const dwarf::Tag Tag = Die.getTag();
  // Skip function types.
  if (Tag == dwarf::DW_TAG_subroutine_type)
    return;

  // Handle any kind of lexical scope.
  const bool HasAbstractOrigin =
      Die.find(dwarf::DW_AT_abstract_origin) != std::nullopt;
  const bool IsFunction = Tag == dwarf::DW_TAG_subprogram;
  const bool IsBlock = Tag == dwarf::DW_TAG_lexical_block;
  const bool IsInlinedFunction = Tag == dwarf::DW_TAG_inlined_subroutine;
  // We want to know how many variables (with abstract_origin) don't have
  // location info.
  const bool IsCandidateForZeroLocCovTracking =
      (IsInlinedFunction || (IsFunction && HasAbstractOrigin));

  AbstractOriginVarsTy AbstractOriginVars;

  // Get the vars of the inlined fn, so the locstats
  // reports the missing vars (with coverage 0%).
  if (IsCandidateForZeroLocCovTracking) {
    auto OffsetFn = Die.find(dwarf::DW_AT_abstract_origin);
    if (OffsetFn) {
      uint64_t OffsetOfInlineFnCopy = (*OffsetFn).getRawUValue();
      if (auto It = LocalAbstractOriginFnInfo.find(OffsetOfInlineFnCopy);
          It != LocalAbstractOriginFnInfo.end()) {
        AbstractOriginVars = It->second;
        AbstractOriginVarsPtr = &AbstractOriginVars;
      } else {
        // This means that the DW_AT_inline fn copy is out of order
        // or that the abstract_origin references another CU,
        // so this abstract origin instance will be processed later.
        FnsWithAbstractOriginToBeProcessed.push_back(Die.getOffset());
        AbstractOriginVarsPtr = nullptr;
      }
    }
  }

  if (IsFunction || IsInlinedFunction || IsBlock) {
    // Reset VarPrefix when entering a new function.
    if (IsFunction || IsInlinedFunction)
      VarPrefix = "v";

    // Ignore forward declarations.
    if (Die.find(dwarf::DW_AT_declaration))
      return;

    // Check for call sites.
    if (Die.find(dwarf::DW_AT_call_file) && Die.find(dwarf::DW_AT_call_line))
      GlobalStats.CallSiteEntries++;

    // PC Ranges.
    auto RangesOrError = Die.getAddressRanges();
    if (!RangesOrError) {
      llvm::consumeError(RangesOrError.takeError());
      return;
    }

    auto Ranges = RangesOrError.get();
    uint64_t BytesInThisScope = 0;
    for (auto Range : Ranges)
      BytesInThisScope += Range.HighPC - Range.LowPC;

    // Count the function.
    if (!IsBlock) {
      // Skip over abstract origins, but collect variables
      // from it so it can be used for location statistics
      // for inlined instancies.
      if (Die.find(dwarf::DW_AT_inline)) {
        uint64_t SPOffset = Die.getOffset();
        AbstractOriginFnCUs[SPOffset] = Die.getDwarfUnit();
        collectAbstractOriginFnInfo(Die, SPOffset, GlobalAbstractOriginFnInfo,
                                    LocalAbstractOriginFnInfo);
        return;
      }

      std::string FnID = constructDieID(Die);
      // We've seen an instance of this function.
      auto &FnStats = FnStatMap[FnID];
      FnStats.IsFunction = true;
      if (IsInlinedFunction) {
        FnStats.NumFnInlined++;
        if (Die.findRecursively(dwarf::DW_AT_abstract_origin))
          FnStats.NumAbstractOrigins++;
      } else {
        FnStats.NumFnOutOfLine++;
      }
      if (Die.findRecursively(dwarf::DW_AT_decl_file) &&
          Die.findRecursively(dwarf::DW_AT_decl_line))
        FnStats.HasSourceLocation = true;
      // Update function prefix.
      FnPrefix = FnID;
    }

    if (BytesInThisScope) {
      BytesInScope = BytesInThisScope;
      if (IsFunction)
        GlobalStats.FunctionSize += BytesInThisScope;
      else if (IsInlinedFunction && InlineDepth == 0)
        GlobalStats.InlineFunctionSize += BytesInThisScope;
    }
  } else {
    // Not a scope, visit the Die itself. It could be a variable.
    collectStatsForDie(Die, FnPrefix, VarPrefix, BytesInScope, InlineDepth,
                       FnStatMap, GlobalStats, LocStats, AbstractOriginVarsPtr);
  }

  // Set InlineDepth correctly for child recursion
  if (IsFunction)
    InlineDepth = 0;
  else if (IsInlinedFunction)
    ++InlineDepth;

  // Traverse children.
  unsigned LexicalBlockIndex = 0;
  unsigned FormalParameterIndex = 0;
  DWARFDie Child = Die.getFirstChild();
  while (Child) {
    std::string ChildVarPrefix = VarPrefix;
    if (Child.getTag() == dwarf::DW_TAG_lexical_block)
      ChildVarPrefix += toHex(LexicalBlockIndex++) + '.';
    if (Child.getTag() == dwarf::DW_TAG_formal_parameter)
      ChildVarPrefix += 'p' + toHex(FormalParameterIndex++) + '.';

    collectStatsRecursive(
        Child, FnPrefix, ChildVarPrefix, BytesInScope, InlineDepth, FnStatMap,
        GlobalStats, LocStats, AbstractOriginFnCUs, GlobalAbstractOriginFnInfo,
        LocalAbstractOriginFnInfo, FnsWithAbstractOriginToBeProcessed,
        AbstractOriginVarsPtr);
    Child = Child.getSibling();
  }

  if (!IsCandidateForZeroLocCovTracking)
    return;

  // After we have processed all vars of the inlined function (or function with
  // an abstract_origin), we want to know how many variables have no location.
  for (auto Offset : AbstractOriginVars) {
    LocStats.NumVarParam++;
    LocStats.VarParamLocStats[ZeroCoverageBucket]++;
    auto FnDie = Die.getDwarfUnit()->getDIEForOffset(Offset);
    if (!FnDie)
      continue;
    auto Tag = FnDie.getTag();
    if (Tag == dwarf::DW_TAG_formal_parameter) {
      LocStats.NumParam++;
      LocStats.ParamLocStats[ZeroCoverageBucket]++;
    } else if (Tag == dwarf::DW_TAG_variable) {
      LocStats.NumVar++;
      LocStats.LocalVarLocStats[ZeroCoverageBucket]++;
    }
  }
}

/// Print human-readable output.
/// \{
static void printDatum(json::OStream &J, const char *Key, json::Value Value) {
  if (Value == OverflowValue)
    J.attribute(Key, "overflowed");
  else
    J.attribute(Key, Value);

  LLVM_DEBUG(llvm::dbgs() << Key << ": " << Value << '\n');
}

static void printLocationStats(json::OStream &J, const char *Key,
                               std::vector<SaturatingUINT64> &LocationStats) {
  if (LocationStats[0].Value == OverflowValue)
    J.attribute((Twine(Key) +
                 " with (0%,10%) of parent scope covered by DW_AT_location")
                    .str(),
                "overflowed");
  else
    J.attribute(
        (Twine(Key) + " with 0% of parent scope covered by DW_AT_location")
            .str(),
        LocationStats[0].Value);
  LLVM_DEBUG(
      llvm::dbgs() << Key
                   << " with 0% of parent scope covered by DW_AT_location: \\"
                   << LocationStats[0].Value << '\n');

  if (LocationStats[1].Value == OverflowValue)
    J.attribute((Twine(Key) +
                 " with (0%,10%) of parent scope covered by DW_AT_location")
                    .str(),
                "overflowed");
  else
    J.attribute((Twine(Key) +
                 " with (0%,10%) of parent scope covered by DW_AT_location")
                    .str(),
                LocationStats[1].Value);
  LLVM_DEBUG(llvm::dbgs()
             << Key
             << " with (0%,10%) of parent scope covered by DW_AT_location: "
             << LocationStats[1].Value << '\n');

  for (unsigned i = 2; i < NumOfCoverageCategories - 1; ++i) {
    if (LocationStats[i].Value == OverflowValue)
      J.attribute((Twine(Key) + " with [" + Twine((i - 1) * 10) + "%," +
                   Twine(i * 10) +
                   "%) of parent scope covered by DW_AT_location")
                      .str(),
                  "overflowed");
    else
      J.attribute((Twine(Key) + " with [" + Twine((i - 1) * 10) + "%," +
                   Twine(i * 10) +
                   "%) of parent scope covered by DW_AT_location")
                      .str(),
                  LocationStats[i].Value);
    LLVM_DEBUG(llvm::dbgs()
               << Key << " with [" << (i - 1) * 10 << "%," << i * 10
               << "%) of parent scope covered by DW_AT_location: "
               << LocationStats[i].Value);
  }
  if (LocationStats[NumOfCoverageCategories - 1].Value == OverflowValue)
    J.attribute(
        (Twine(Key) + " with 100% of parent scope covered by DW_AT_location")
            .str(),
        "overflowed");
  else
    J.attribute(
        (Twine(Key) + " with 100% of parent scope covered by DW_AT_location")
            .str(),
        LocationStats[NumOfCoverageCategories - 1].Value);
  LLVM_DEBUG(
      llvm::dbgs() << Key
                   << " with 100% of parent scope covered by DW_AT_location: "
                   << LocationStats[NumOfCoverageCategories - 1].Value);
}

static void printSectionSizes(json::OStream &J, const SectionSizes &Sizes) {
  for (const auto &It : Sizes.DebugSectionSizes)
    J.attribute((Twine("#bytes in ") + It.first).str(), int64_t(It.second));
}

/// Stop tracking variables that contain abstract_origin with a location.
/// This is used for out-of-order DW_AT_inline subprograms only.
static void updateVarsWithAbstractOriginLocCovInfo(
    DWARFDie FnDieWithAbstractOrigin,
    AbstractOriginVarsTy &AbstractOriginVars) {
  DWARFDie Child = FnDieWithAbstractOrigin.getFirstChild();
  while (Child) {
    const dwarf::Tag ChildTag = Child.getTag();
    if ((ChildTag == dwarf::DW_TAG_formal_parameter ||
         ChildTag == dwarf::DW_TAG_variable) &&
        (Child.find(dwarf::DW_AT_location) ||
         Child.find(dwarf::DW_AT_const_value))) {
      auto OffsetVar = Child.find(dwarf::DW_AT_abstract_origin);
      if (OffsetVar)
        llvm::erase(AbstractOriginVars, (*OffsetVar).getRawUValue());
    } else if (ChildTag == dwarf::DW_TAG_lexical_block)
      updateVarsWithAbstractOriginLocCovInfo(Child, AbstractOriginVars);
    Child = Child.getSibling();
  }
}

/// Collect zero location coverage for inlined variables which refer to
/// a DW_AT_inline copy of subprogram that is out of order in the DWARF.
/// Also cover the variables of a concrete function (represented with
/// the DW_TAG_subprogram) with an abstract_origin attribute.
static void collectZeroLocCovForVarsWithAbstractOrigin(
    DWARFUnit *DwUnit, GlobalStats &GlobalStats, LocationStats &LocStats,
    AbstractOriginVarsTyMap &LocalAbstractOriginFnInfo,
    FunctionsWithAbstractOriginTy &FnsWithAbstractOriginToBeProcessed) {
  // The next variable is used to filter out functions that have been processed,
  // leaving FnsWithAbstractOriginToBeProcessed with just CrossCU references.
  FunctionsWithAbstractOriginTy ProcessedFns;
  for (auto FnOffset : FnsWithAbstractOriginToBeProcessed) {
    DWARFDie FnDieWithAbstractOrigin = DwUnit->getDIEForOffset(FnOffset);
    auto FnCopy = FnDieWithAbstractOrigin.find(dwarf::DW_AT_abstract_origin);
    AbstractOriginVarsTy AbstractOriginVars;
    if (!FnCopy)
      continue;
    uint64_t FnCopyRawUValue = (*FnCopy).getRawUValue();
    // If there is no entry within LocalAbstractOriginFnInfo for the given
    // FnCopyRawUValue, function isn't out-of-order in DWARF. Rather, we have
    // CrossCU referencing.
    auto It = LocalAbstractOriginFnInfo.find(FnCopyRawUValue);
    if (It == LocalAbstractOriginFnInfo.end())
      continue;
    AbstractOriginVars = It->second;
    updateVarsWithAbstractOriginLocCovInfo(FnDieWithAbstractOrigin,
                                           AbstractOriginVars);

    for (auto Offset : AbstractOriginVars) {
      LocStats.NumVarParam++;
      LocStats.VarParamLocStats[ZeroCoverageBucket]++;
      auto Tag = DwUnit->getDIEForOffset(Offset).getTag();
      if (Tag == dwarf::DW_TAG_formal_parameter) {
        LocStats.NumParam++;
        LocStats.ParamLocStats[ZeroCoverageBucket]++;
      } else if (Tag == dwarf::DW_TAG_variable) {
        LocStats.NumVar++;
        LocStats.LocalVarLocStats[ZeroCoverageBucket]++;
      }
    }
    ProcessedFns.push_back(FnOffset);
  }
  for (auto ProcessedFn : ProcessedFns)
    llvm::erase(FnsWithAbstractOriginToBeProcessed, ProcessedFn);
}

/// Collect zero location coverage for inlined variables which refer to
/// a DW_AT_inline copy of subprogram that is in a different CU.
static void collectZeroLocCovForVarsWithCrossCUReferencingAbstractOrigin(
    LocationStats &LocStats, FunctionDIECUTyMap AbstractOriginFnCUs,
    AbstractOriginVarsTyMap &GlobalAbstractOriginFnInfo,
    CrossCUReferencingDIELocationTy &CrossCUReferencesToBeResolved) {
  for (const auto &CrossCUReferenceToBeResolved :
       CrossCUReferencesToBeResolved) {
    DWARFUnit *DwUnit = CrossCUReferenceToBeResolved.DwUnit;
    DWARFDie FnDIEWithCrossCUReferencing =
        DwUnit->getDIEForOffset(CrossCUReferenceToBeResolved.DIEOffset);
    auto FnCopy =
        FnDIEWithCrossCUReferencing.find(dwarf::DW_AT_abstract_origin);
    if (!FnCopy)
      continue;
    uint64_t FnCopyRawUValue = (*FnCopy).getRawUValue();
    AbstractOriginVarsTy AbstractOriginVars =
        GlobalAbstractOriginFnInfo[FnCopyRawUValue];
    updateVarsWithAbstractOriginLocCovInfo(FnDIEWithCrossCUReferencing,
                                           AbstractOriginVars);
    for (auto Offset : AbstractOriginVars) {
      LocStats.NumVarParam++;
      LocStats.VarParamLocStats[ZeroCoverageBucket]++;
      auto Tag = (AbstractOriginFnCUs[FnCopyRawUValue])
                     ->getDIEForOffset(Offset)
                     .getTag();
      if (Tag == dwarf::DW_TAG_formal_parameter) {
        LocStats.NumParam++;
        LocStats.ParamLocStats[ZeroCoverageBucket]++;
      } else if (Tag == dwarf::DW_TAG_variable) {
        LocStats.NumVar++;
        LocStats.LocalVarLocStats[ZeroCoverageBucket]++;
      }
    }
  }
}

/// \}

/// Collect debug info quality metrics for an entire DIContext.
///
/// Do the impossible and reduce the quality of the debug info down to a few
/// numbers. The idea is to condense the data into numbers that can be tracked
/// over time to identify trends in newer compiler versions and gauge the effect
/// of particular optimizations. The raw numbers themselves are not particularly
/// useful, only the delta between compiling the same program with different
/// compilers is.
bool dwarfdump::collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
                                          const Twine &Filename,
                                          raw_ostream &OS) {
  StringRef FormatName = Obj.getFileFormatName();
  GlobalStats GlobalStats;
  LocationStats LocStats;
  LineStats LnStats;
  StringMap<PerFunctionStats> Statistics;
  // This variable holds variable information for functions with
  // abstract_origin globally, across all CUs.
  AbstractOriginVarsTyMap GlobalAbstractOriginFnInfo;
  // This variable holds information about the CU of a function with
  // abstract_origin.
  FunctionDIECUTyMap AbstractOriginFnCUs;
  CrossCUReferencingDIELocationTy CrossCUReferencesToBeResolved;
  // Tuple representing a single source code position in the line table. Fields
  // are respectively: Line, Col, File, where 'File' is an index into the Files
  // vector below.
  using LineTuple = std::tuple<uint32_t, uint16_t, uint16_t>;
  SmallVector<std::string> Files;
  DenseSet<LineTuple> UniqueLines;
  DenseSet<LineTuple> UniqueNonZeroLines;

  for (const auto &CU : DICtx.compile_units()) {
    if (DWARFDie CUDie = CU->getNonSkeletonUnitDIE(false)) {
      // This variable holds variable information for functions with
      // abstract_origin, but just for the current CU.
      AbstractOriginVarsTyMap LocalAbstractOriginFnInfo;
      FunctionsWithAbstractOriginTy FnsWithAbstractOriginToBeProcessed;

      collectStatsRecursive(
          CUDie, "/", "g", 0, 0, Statistics, GlobalStats, LocStats,
          AbstractOriginFnCUs, GlobalAbstractOriginFnInfo,
          LocalAbstractOriginFnInfo, FnsWithAbstractOriginToBeProcessed);

      // collectZeroLocCovForVarsWithAbstractOrigin will filter out all
      // out-of-order DWARF functions that have been processed within it,
      // leaving FnsWithAbstractOriginToBeProcessed with only CrossCU
      // references.
      collectZeroLocCovForVarsWithAbstractOrigin(
          CUDie.getDwarfUnit(), GlobalStats, LocStats,
          LocalAbstractOriginFnInfo, FnsWithAbstractOriginToBeProcessed);

      // Collect all CrossCU references into CrossCUReferencesToBeResolved.
      for (auto CrossCUReferencingDIEOffset :
           FnsWithAbstractOriginToBeProcessed)
        CrossCUReferencesToBeResolved.push_back(
            DIELocation(CUDie.getDwarfUnit(), CrossCUReferencingDIEOffset));
    }
    const auto *LineTable = DICtx.getLineTableForUnit(CU.get());
    std::optional<uint64_t> LastFileIdxOpt;
    if (LineTable)
      LastFileIdxOpt = LineTable->getLastValidFileIndex();
    if (LastFileIdxOpt) {
      // Each CU has its own file index; in order to track unique line entries
      // across CUs, we therefore need to map each CU file index to a global
      // file index, which we store here.
      DenseMap<uint64_t, uint16_t> CUFileMapping;
      for (uint64_t FileIdx = 0; FileIdx <= *LastFileIdxOpt; ++FileIdx) {
        std::string File;
        if (LineTable->getFileNameByIndex(
                FileIdx, CU->getCompilationDir(),
                DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
                File)) {
          auto ExistingFile = llvm::find(Files, File);
          if (ExistingFile != Files.end()) {
            CUFileMapping[FileIdx] = std::distance(Files.begin(), ExistingFile);
          } else {
            CUFileMapping[FileIdx] = Files.size();
            Files.push_back(File);
          }
        }
      }
      for (const auto &Seq : LineTable->Sequences) {
        LnStats.NumBytes += Seq.HighPC - Seq.LowPC;
        // Ignore the `end_sequence` entry, since it's not interesting for us.
        LnStats.NumEntries += Seq.LastRowIndex - Seq.FirstRowIndex - 1;
        for (size_t RowIdx = Seq.FirstRowIndex; RowIdx < Seq.LastRowIndex - 1;
             ++RowIdx) {
          auto Entry = LineTable->Rows[RowIdx];
          if (Entry.IsStmt)
            LnStats.NumIsStmtEntries += 1;
          assert(CUFileMapping.contains(Entry.File) &&
                 "Should have been collected earlier!");
          uint16_t MappedFile = CUFileMapping[Entry.File];
          UniqueLines.insert({Entry.Line, Entry.Column, MappedFile});
          if (Entry.Line != 0) {
            UniqueNonZeroLines.insert({Entry.Line, Entry.Column, MappedFile});
          } else {
            auto EntryStartAddress = Entry.Address.Address;
            auto EntryEndAddress = LineTable->Rows[RowIdx + 1].Address.Address;
            LnStats.NumLineZeroBytes += EntryEndAddress - EntryStartAddress;
          }
        }
      }
    }
  }

  LnStats.NumUniqueEntries = UniqueLines.size();
  LnStats.NumUniqueNonZeroEntries = UniqueNonZeroLines.size();

  /// Resolve CrossCU references.
  collectZeroLocCovForVarsWithCrossCUReferencingAbstractOrigin(
      LocStats, AbstractOriginFnCUs, GlobalAbstractOriginFnInfo,
      CrossCUReferencesToBeResolved);

  /// Collect the sizes of debug sections.
  SectionSizes Sizes;
  calculateSectionSizes(Obj, Sizes, Filename);

  /// The version number should be increased every time the algorithm is changed
  /// (including bug fixes). New metrics may be added without increasing the
  /// version.
  unsigned Version = 9;
  SaturatingUINT64 VarParamTotal = 0;
  SaturatingUINT64 VarParamUnique = 0;
  SaturatingUINT64 VarParamWithLoc = 0;
  SaturatingUINT64 NumFunctions = 0;
  SaturatingUINT64 NumOutOfLineFunctions = 0;
  SaturatingUINT64 NumInlinedFunctions = 0;
  SaturatingUINT64 NumFuncsWithSrcLoc = 0;
  SaturatingUINT64 NumAbstractOrigins = 0;
  SaturatingUINT64 ParamTotal = 0;
  SaturatingUINT64 ParamWithType = 0;
  SaturatingUINT64 ParamWithLoc = 0;
  SaturatingUINT64 ParamWithSrcLoc = 0;
  SaturatingUINT64 LocalVarTotal = 0;
  SaturatingUINT64 LocalVarWithType = 0;
  SaturatingUINT64 LocalVarWithSrcLoc = 0;
  SaturatingUINT64 LocalVarWithLoc = 0;
  for (auto &Entry : Statistics) {
    PerFunctionStats &Stats = Entry.getValue();
    uint64_t TotalVars = Stats.VarsInFunction.size() *
                         (Stats.NumFnInlined + Stats.NumFnOutOfLine);
    // Count variables in global scope.
    if (!Stats.IsFunction)
      TotalVars =
          Stats.NumLocalVars + Stats.ConstantMembers + Stats.NumArtificial;
    uint64_t Constants = Stats.ConstantMembers;
    VarParamWithLoc += Stats.TotalVarWithLoc + Constants;
    VarParamTotal += TotalVars;
    VarParamUnique += Stats.VarsInFunction.size();
    LLVM_DEBUG(for (auto &V
                    : Stats.VarsInFunction) llvm::dbgs()
               << Entry.getKey() << ": " << V.getKey() << "\n");
    NumFunctions += Stats.IsFunction;
    NumFuncsWithSrcLoc += Stats.HasSourceLocation;
    NumOutOfLineFunctions += Stats.IsFunction * Stats.NumFnOutOfLine;
    NumInlinedFunctions += Stats.IsFunction * Stats.NumFnInlined;
    NumAbstractOrigins += Stats.IsFunction * Stats.NumAbstractOrigins;
    ParamTotal += Stats.NumParams;
    ParamWithType += Stats.NumParamTypes;
    ParamWithLoc += Stats.NumParamLocations;
    ParamWithSrcLoc += Stats.NumParamSourceLocations;
    LocalVarTotal += Stats.NumLocalVars;
    LocalVarWithType += Stats.NumLocalVarTypes;
    LocalVarWithLoc += Stats.NumLocalVarLocations;
    LocalVarWithSrcLoc += Stats.NumLocalVarSourceLocations;
  }

  // Print summary.
  OS.SetBufferSize(1024);
  json::OStream J(OS, 2);
  J.objectBegin();
  J.attribute("version", Version);
  LLVM_DEBUG(llvm::dbgs() << "Variable location quality metrics\n";
             llvm::dbgs() << "---------------------------------\n");

  printDatum(J, "file", Filename.str());
  printDatum(J, "format", FormatName);

  printDatum(J, "#functions", NumFunctions.Value);
  printDatum(J, "#functions with location", NumFuncsWithSrcLoc.Value);
  printDatum(J, "#out-of-line functions", NumOutOfLineFunctions.Value);
  printDatum(J, "#inlined functions", NumInlinedFunctions.Value);
  printDatum(J, "#inlined functions with abstract origins",
             NumAbstractOrigins.Value);

  // This includes local variables and formal parameters.
  printDatum(J, "#unique source variables", VarParamUnique.Value);
  printDatum(J, "#source variables", VarParamTotal.Value);
  printDatum(J, "#source variables with location", VarParamWithLoc.Value);

  printDatum(J, "#call site entries", GlobalStats.CallSiteEntries.Value);
  printDatum(J, "#call site DIEs", GlobalStats.CallSiteDIEs.Value);
  printDatum(J, "#call site parameter DIEs",
             GlobalStats.CallSiteParamDIEs.Value);

  printDatum(J, "sum_all_variables(#bytes in parent scope)",
             GlobalStats.ScopeBytes.Value);
  printDatum(J,
             "sum_all_variables(#bytes in any scope covered by DW_AT_location)",
             GlobalStats.TotalBytesCovered.Value);
  printDatum(J,
             "sum_all_variables(#bytes in parent scope covered by "
             "DW_AT_location)",
             GlobalStats.ScopeBytesCovered.Value);
  printDatum(J,
             "sum_all_variables(#bytes in parent scope covered by "
             "DW_OP_entry_value)",
             GlobalStats.ScopeEntryValueBytesCovered.Value);

  printDatum(J, "sum_all_params(#bytes in parent scope)",
             GlobalStats.ParamScopeBytes.Value);
  printDatum(J,
             "sum_all_params(#bytes in parent scope covered by DW_AT_location)",
             GlobalStats.ParamScopeBytesCovered.Value);
  printDatum(J,
             "sum_all_params(#bytes in parent scope covered by "
             "DW_OP_entry_value)",
             GlobalStats.ParamScopeEntryValueBytesCovered.Value);

  printDatum(J, "sum_all_local_vars(#bytes in parent scope)",
             GlobalStats.LocalVarScopeBytes.Value);
  printDatum(J,
             "sum_all_local_vars(#bytes in parent scope covered by "
             "DW_AT_location)",
             GlobalStats.LocalVarScopeBytesCovered.Value);
  printDatum(J,
             "sum_all_local_vars(#bytes in parent scope covered by "
             "DW_OP_entry_value)",
             GlobalStats.LocalVarScopeEntryValueBytesCovered.Value);

  printDatum(J, "#bytes within functions", GlobalStats.FunctionSize.Value);
  printDatum(J, "#bytes within inlined functions",
             GlobalStats.InlineFunctionSize.Value);

  // Print the summary for formal parameters.
  printDatum(J, "#params", ParamTotal.Value);
  printDatum(J, "#params with source location", ParamWithSrcLoc.Value);
  printDatum(J, "#params with type", ParamWithType.Value);
  printDatum(J, "#params with binary location", ParamWithLoc.Value);

  // Print the summary for local variables.
  printDatum(J, "#local vars", LocalVarTotal.Value);
  printDatum(J, "#local vars with source location", LocalVarWithSrcLoc.Value);
  printDatum(J, "#local vars with type", LocalVarWithType.Value);
  printDatum(J, "#local vars with binary location", LocalVarWithLoc.Value);

  // Print the debug section sizes.
  printSectionSizes(J, Sizes);

  // Print the location statistics for variables (includes local variables
  // and formal parameters).
  printDatum(J, "#variables processed by location statistics",
             LocStats.NumVarParam.Value);
  printLocationStats(J, "#variables", LocStats.VarParamLocStats);
  printLocationStats(J, "#variables - entry values",
                     LocStats.VarParamNonEntryValLocStats);

  // Print the location statistics for formal parameters.
  printDatum(J, "#params processed by location statistics",
             LocStats.NumParam.Value);
  printLocationStats(J, "#params", LocStats.ParamLocStats);
  printLocationStats(J, "#params - entry values",
                     LocStats.ParamNonEntryValLocStats);

  // Print the location statistics for local variables.
  printDatum(J, "#local vars processed by location statistics",
             LocStats.NumVar.Value);
  printLocationStats(J, "#local vars", LocStats.LocalVarLocStats);
  printLocationStats(J, "#local vars - entry values",
                     LocStats.LocalVarNonEntryValLocStats);

  // Print line statistics for the object file.
  printDatum(J, "#bytes with line information", LnStats.NumBytes.Value);
  printDatum(J, "#bytes with line-0 locations", LnStats.NumLineZeroBytes.Value);
  printDatum(J, "#line entries", LnStats.NumEntries.Value);
  printDatum(J, "#line entries (is_stmt)", LnStats.NumIsStmtEntries.Value);
  printDatum(J, "#line entries (unique)", LnStats.NumUniqueEntries.Value);
  printDatum(J, "#line entries (unique non-0)",
             LnStats.NumUniqueNonZeroEntries.Value);

  J.objectEnd();
  OS << '\n';
  LLVM_DEBUG(
      llvm::dbgs() << "Total Availability: "
                   << (VarParamTotal.Value
                           ? (int)std::round((VarParamWithLoc.Value * 100.0) /
                                             VarParamTotal.Value)
                           : 0)
                   << "%\n";
      llvm::dbgs() << "PC Ranges covered: "
                   << (GlobalStats.ScopeBytes.Value
                           ? (int)std::round(
                                 (GlobalStats.ScopeBytesCovered.Value * 100.0) /
                                 GlobalStats.ScopeBytes.Value)
                           : 0)
                   << "%\n");
  return true;
}
