Esempio n. 1
0
  /// \brief Render the CoverageMapping object.
  void renderRoot() {
    // Start Root of JSON object.
    emitDictStart();

    emitDictElement("version", LLVM_COVERAGE_EXPORT_JSON_STR);
    emitDictElement("type", LLVM_COVERAGE_EXPORT_JSON_TYPE_STR);
    emitDictKey("data");

    // Start List of Exports.
    emitArrayStart();

    // Start Export.
    emitDictStart();
    emitDictElement("object", getObjectFilename());

    emitDictKey("files");

    FileCoverageSummary Totals = FileCoverageSummary("Totals");
    std::vector<std::string> SourceFiles;
    for (StringRef SF : Coverage.getUniqueSourceFiles())
      SourceFiles.emplace_back(SF);
    auto FileReports =
        CoverageReport::prepareFileReports(Coverage, Totals, SourceFiles);
    renderFiles(SourceFiles, FileReports);

    emitDictKey("functions");
    renderFunctions(Coverage.getCoveredFunctions());

    emitDictKey("totals");
    renderSummary(Totals);

    // End Export.
    emitDictEnd();

    // End List of Exports.
    emitArrayEnd();

    // End Root of JSON Object.
    emitDictEnd();

    assert((State.top() == JsonState::None) &&
           "All Elements In JSON were Closed");
  }
Esempio n. 2
0
void CodeCoverageTool::demangleSymbols(const CoverageMapping &Coverage) {
  if (!ViewOpts.hasDemangler())
    return;

  // Pass function names to the demangler in a temporary file.
  int InputFD;
  SmallString<256> InputPath;
  std::error_code EC =
      sys::fs::createTemporaryFile("demangle-in", "list", InputFD, InputPath);
  if (EC) {
    error(InputPath, EC.message());
    return;
  }
  tool_output_file InputTOF{InputPath, InputFD};

  unsigned NumSymbols = 0;
  for (const auto &Function : Coverage.getCoveredFunctions()) {
    InputTOF.os() << Function.Name << '\n';
    ++NumSymbols;
  }
  InputTOF.os().close();

  // Use another temporary file to store the demangler's output.
  int OutputFD;
  SmallString<256> OutputPath;
  EC = sys::fs::createTemporaryFile("demangle-out", "list", OutputFD,
                                    OutputPath);
  if (EC) {
    error(OutputPath, EC.message());
    return;
  }
  tool_output_file OutputTOF{OutputPath, OutputFD};
  OutputTOF.os().close();

  // Invoke the demangler.
  std::vector<const char *> ArgsV;
  for (const std::string &Arg : ViewOpts.DemanglerOpts)
    ArgsV.push_back(Arg.c_str());
  ArgsV.push_back(nullptr);
  StringRef InputPathRef = InputPath.str();
  StringRef OutputPathRef = OutputPath.str();
  StringRef StderrRef;
  const StringRef *Redirects[] = {&InputPathRef, &OutputPathRef, &StderrRef};
  std::string ErrMsg;
  int RC = sys::ExecuteAndWait(ViewOpts.DemanglerOpts[0], ArgsV.data(),
                               /*env=*/nullptr, Redirects, /*secondsToWait=*/0,
                               /*memoryLimit=*/0, &ErrMsg);
  if (RC) {
    error(ErrMsg, ViewOpts.DemanglerOpts[0]);
    return;
  }

  // Parse the demangler's output.
  auto BufOrError = MemoryBuffer::getFile(OutputPath);
  if (!BufOrError) {
    error(OutputPath, BufOrError.getError().message());
    return;
  }

  std::unique_ptr<MemoryBuffer> DemanglerBuf = std::move(*BufOrError);

  SmallVector<StringRef, 8> Symbols;
  StringRef DemanglerData = DemanglerBuf->getBuffer();
  DemanglerData.split(Symbols, '\n', /*MaxSplit=*/NumSymbols,
                      /*KeepEmpty=*/false);
  if (Symbols.size() != NumSymbols) {
    error("Demangler did not provide expected number of symbols");
    return;
  }

  // Cache the demangled names.
  unsigned I = 0;
  for (const auto &Function : Coverage.getCoveredFunctions())
    DemangledNames[Function.Name] = Symbols[I++];
}