brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 9881596 Raw
80 lines · cpp
1//===------- SARIFDiagnosticPrinter.cpp - Diagnostic Printer---------------===//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// This diagnostic client prints out their diagnostic messages in SARIF format.10//11//===----------------------------------------------------------------------===//12 13#include "clang/Frontend/SARIFDiagnosticPrinter.h"14#include "clang/Basic/DiagnosticOptions.h"15#include "clang/Basic/Sarif.h"16#include "clang/Frontend/DiagnosticRenderer.h"17#include "clang/Frontend/SARIFDiagnostic.h"18#include "clang/Lex/Lexer.h"19#include "llvm/Support/ErrorHandling.h"20#include "llvm/Support/JSON.h"21#include "llvm/Support/raw_ostream.h"22 23namespace clang {24 25SARIFDiagnosticPrinter::SARIFDiagnosticPrinter(raw_ostream &OS,26                                               DiagnosticOptions &DiagOpts)27    : OS(OS), DiagOpts(DiagOpts) {}28 29void SARIFDiagnosticPrinter::BeginSourceFile(const LangOptions &LO,30                                             const Preprocessor *PP) {31  // Build the SARIFDiagnostic utility.32  assert(hasSarifWriter() && "Writer not set!");33  assert(!SARIFDiag && "SARIFDiagnostic already set.");34  SARIFDiag = std::make_unique<SARIFDiagnostic>(OS, LO, DiagOpts, &*Writer);35  // Initialize the SARIF object.36  Writer->createRun("clang", Prefix);37}38 39void SARIFDiagnosticPrinter::EndSourceFile() {40  assert(SARIFDiag && "SARIFDiagnostic has not been set.");41  Writer->endRun();42  llvm::json::Value Value(Writer->createDocument());43  OS << "\n" << Value << "\n\n";44  OS.flush();45  SARIFDiag.reset();46}47 48void SARIFDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,49                                              const Diagnostic &Info) {50  assert(SARIFDiag && "SARIFDiagnostic has not been set.");51  // Default implementation (Warnings/errors count). Keeps track of the52  // number of errors.53  DiagnosticConsumer::HandleDiagnostic(Level, Info);54 55  // Render the diagnostic message into a temporary buffer eagerly. We'll use56  // this later as we add the diagnostic to the SARIF object.57  SmallString<100> OutStr;58  Info.FormatDiagnostic(OutStr);59 60  llvm::raw_svector_ostream DiagMessageStream(OutStr);61 62  // Use a dedicated, simpler path for diagnostics without a valid location.63  // This is important as if the location is missing, we may be emitting64  // diagnostics in a context that lacks language options, a source manager, or65  // other infrastructure necessary when emitting more rich diagnostics.66  if (Info.getLocation().isInvalid()) {67    // FIXME: Enable diagnostics without a source manager68    return;69  }70 71  // Assert that the rest of our infrastructure is setup properly.72  assert(Info.hasSourceManager() &&73         "Unexpected diagnostic with no source manager");74 75  SARIFDiag->emitDiagnostic(76      FullSourceLoc(Info.getLocation(), Info.getSourceManager()), Level,77      DiagMessageStream.str(), Info.getRanges(), Info.getFixItHints(), &Info);78}79} // namespace clang80