brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 6fee154 Raw
92 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "ClangTidyProfiling.h"10#include "llvm/ADT/SmallString.h"11#include "llvm/Support/FileSystem.h"12#include "llvm/Support/Path.h"13#include "llvm/Support/raw_ostream.h"14#include <optional>15#include <system_error>16#include <utility>17 18#define DEBUG_TYPE "clang-tidy-profiling"19 20namespace clang::tidy {21 22ClangTidyProfiling::StorageParams::StorageParams(llvm::StringRef ProfilePrefix,23                                                 llvm::StringRef SourceFile)24    : Timestamp(std::chrono::system_clock::now()), SourceFilename(SourceFile) {25  llvm::SmallString<32> TimestampStr;26  llvm::raw_svector_ostream OS(TimestampStr);27  llvm::format_provider<decltype(Timestamp)>::format(Timestamp, OS,28                                                     "%Y%m%d%H%M%S%N");29 30  llvm::SmallString<256> FinalPrefix(ProfilePrefix);31  llvm::sys::path::append(FinalPrefix, TimestampStr);32 33  // So the full output name is: /ProfilePrefix/timestamp-inputfilename.json34  StoreFilename = llvm::Twine(FinalPrefix + "-" +35                              llvm::sys::path::filename(SourceFile) + ".json")36                      .str();37}38 39void ClangTidyProfiling::printUserFriendlyTable(llvm::raw_ostream &OS,40                                                llvm::TimerGroup &TG) {41  TG.print(OS);42  OS.flush();43}44 45void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS,46                                     llvm::TimerGroup &TG) {47  OS << "{\n";48  OS << R"("file": ")" << Storage->SourceFilename << "\",\n";49  OS << R"("timestamp": ")" << Storage->Timestamp << "\",\n";50  OS << "\"profile\": {\n";51  TG.printJSONValues(OS, "");52  OS << "\n}\n";53  OS << "}\n";54  OS.flush();55}56 57void ClangTidyProfiling::storeProfileData(llvm::TimerGroup &TG) {58  assert(Storage && "We should have a filename.");59 60  llvm::SmallString<256> OutputDirectory(Storage->StoreFilename);61  llvm::sys::path::remove_filename(OutputDirectory);62  if (const std::error_code EC =63          llvm::sys::fs::create_directories(OutputDirectory)) {64    llvm::errs() << "Unable to create output directory '" << OutputDirectory65                 << "': " << EC.message() << "\n";66    return;67  }68 69  std::error_code EC;70  llvm::raw_fd_ostream OS(Storage->StoreFilename, EC, llvm::sys::fs::OF_None);71  if (EC) {72    llvm::errs() << "Error opening output file '" << Storage->StoreFilename73                 << "': " << EC.message() << "\n";74    return;75  }76 77  printAsJSON(OS, TG);78}79 80ClangTidyProfiling::ClangTidyProfiling(std::optional<StorageParams> Storage)81    : Storage(std::move(Storage)) {}82 83ClangTidyProfiling::~ClangTidyProfiling() {84  llvm::TimerGroup TG{"clang-tidy", "clang-tidy checks profiling", Records};85  if (!Storage)86    printUserFriendlyTable(llvm::errs(), TG);87  else88    storeProfileData(TG);89}90 91} // namespace clang::tidy92