10b57cec5SDimitry Andric //===--- DiagnosticError.h - Diagnostic payload for llvm::Error -*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 904eeddc0SDimitry Andric #ifndef LLVM_CLANG_BASIC_DIAGNOSTICERROR_H 1004eeddc0SDimitry Andric #define LLVM_CLANG_BASIC_DIAGNOSTICERROR_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "clang/Basic/PartialDiagnostic.h" 130b57cec5SDimitry Andric #include "llvm/Support/Error.h" 14bdd1243dSDimitry Andric #include <optional> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric namespace clang { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric /// Carries a Clang diagnostic in an llvm::Error. 190b57cec5SDimitry Andric /// 200b57cec5SDimitry Andric /// Users should emit the stored diagnostic using the DiagnosticsEngine. 210b57cec5SDimitry Andric class DiagnosticError : public llvm::ErrorInfo<DiagnosticError> { 220b57cec5SDimitry Andric public: DiagnosticError(PartialDiagnosticAt Diag)230b57cec5SDimitry Andric DiagnosticError(PartialDiagnosticAt Diag) : Diag(std::move(Diag)) {} 240b57cec5SDimitry Andric log(raw_ostream & OS)250b57cec5SDimitry Andric void log(raw_ostream &OS) const override { OS << "clang diagnostic"; } 260b57cec5SDimitry Andric getDiagnostic()270b57cec5SDimitry Andric PartialDiagnosticAt &getDiagnostic() { return Diag; } getDiagnostic()280b57cec5SDimitry Andric const PartialDiagnosticAt &getDiagnostic() const { return Diag; } 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric /// Creates a new \c DiagnosticError that contains the given diagnostic at 310b57cec5SDimitry Andric /// the given location. create(SourceLocation Loc,PartialDiagnostic Diag)320b57cec5SDimitry Andric static llvm::Error create(SourceLocation Loc, PartialDiagnostic Diag) { 330b57cec5SDimitry Andric return llvm::make_error<DiagnosticError>( 340b57cec5SDimitry Andric PartialDiagnosticAt(Loc, std::move(Diag))); 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// Extracts and returns the diagnostic payload from the given \c Error if 38*06c3fb27SDimitry Andric /// the error is a \c DiagnosticError. Returns std::nullopt if the given error 39*06c3fb27SDimitry Andric /// is not a \c DiagnosticError. take(llvm::Error & Err)40bdd1243dSDimitry Andric static std::optional<PartialDiagnosticAt> take(llvm::Error &Err) { 41bdd1243dSDimitry Andric std::optional<PartialDiagnosticAt> Result; 420b57cec5SDimitry Andric Err = llvm::handleErrors(std::move(Err), [&](DiagnosticError &E) { 430b57cec5SDimitry Andric Result = std::move(E.getDiagnostic()); 440b57cec5SDimitry Andric }); 450b57cec5SDimitry Andric return Result; 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric static char ID; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric private: 510b57cec5SDimitry Andric // Users are not expected to use error_code. convertToErrorCode()520b57cec5SDimitry Andric std::error_code convertToErrorCode() const override { 530b57cec5SDimitry Andric return llvm::inconvertibleErrorCode(); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric PartialDiagnosticAt Diag; 570b57cec5SDimitry Andric }; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric } // end namespace clang 600b57cec5SDimitry Andric 6104eeddc0SDimitry Andric #endif // LLVM_CLANG_BASIC_DIAGNOSTICERROR_H 62