16103fdfaSHaowei Wu //===- ErrorCollector.cpp -------------------------------------------------===// 26103fdfaSHaowei Wu // 36103fdfaSHaowei Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46103fdfaSHaowei Wu // See https://llvm.org/LICENSE.txt for license information. 56103fdfaSHaowei Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66103fdfaSHaowei Wu // 76103fdfaSHaowei Wu //===-----------------------------------------------------------------------===/ 86103fdfaSHaowei Wu 96103fdfaSHaowei Wu #include "ErrorCollector.h" 106103fdfaSHaowei Wu #include "llvm/Support/Errc.h" 116103fdfaSHaowei Wu #include "llvm/Support/Error.h" 126103fdfaSHaowei Wu #include "llvm/Support/WithColor.h" 136103fdfaSHaowei Wu #include "llvm/Support/raw_ostream.h" 146103fdfaSHaowei Wu #include <vector> 156103fdfaSHaowei Wu 166103fdfaSHaowei Wu using namespace llvm; 176103fdfaSHaowei Wu using namespace llvm::ifs; 186103fdfaSHaowei Wu escalateToFatal()196103fdfaSHaowei Wuvoid ErrorCollector::escalateToFatal() { ErrorsAreFatal = true; } 206103fdfaSHaowei Wu addError(Error && Err,StringRef Tag)216103fdfaSHaowei Wuvoid ErrorCollector::addError(Error &&Err, StringRef Tag) { 226103fdfaSHaowei Wu if (Err) { 236103fdfaSHaowei Wu Errors.push_back(std::move(Err)); 246103fdfaSHaowei Wu Tags.push_back(Tag.str()); 256103fdfaSHaowei Wu } 266103fdfaSHaowei Wu } 276103fdfaSHaowei Wu makeError()286103fdfaSHaowei WuError ErrorCollector::makeError() { 296103fdfaSHaowei Wu // TODO: Make this return something (an AggregateError?) that gives more 306103fdfaSHaowei Wu // individual control over each error and which might be of interest. 316103fdfaSHaowei Wu Error JoinedErrors = Error::success(); 326103fdfaSHaowei Wu for (Error &E : Errors) { 336103fdfaSHaowei Wu JoinedErrors = joinErrors(std::move(JoinedErrors), std::move(E)); 346103fdfaSHaowei Wu } 356103fdfaSHaowei Wu Errors.clear(); 366103fdfaSHaowei Wu Tags.clear(); 376103fdfaSHaowei Wu return JoinedErrors; 386103fdfaSHaowei Wu } 396103fdfaSHaowei Wu log(raw_ostream & OS)406103fdfaSHaowei Wuvoid ErrorCollector::log(raw_ostream &OS) { 416103fdfaSHaowei Wu OS << "Encountered multiple errors:\n"; 426103fdfaSHaowei Wu for (size_t i = 0; i < Errors.size(); ++i) { 436103fdfaSHaowei Wu WithColor::error(OS) << "(" << Tags[i] << ") " << Errors[i]; 446103fdfaSHaowei Wu if (i != Errors.size() - 1) 456103fdfaSHaowei Wu OS << "\n"; 466103fdfaSHaowei Wu } 476103fdfaSHaowei Wu } 486103fdfaSHaowei Wu allErrorsHandled() const496103fdfaSHaowei Wubool ErrorCollector::allErrorsHandled() const { return Errors.empty(); } 506103fdfaSHaowei Wu ~ErrorCollector()516103fdfaSHaowei WuErrorCollector::~ErrorCollector() { 526103fdfaSHaowei Wu if (ErrorsAreFatal && !allErrorsHandled()) 536103fdfaSHaowei Wu fatalUnhandledError(); 546103fdfaSHaowei Wu 556103fdfaSHaowei Wu for (Error &E : Errors) { 566103fdfaSHaowei Wu consumeError(std::move(E)); 576103fdfaSHaowei Wu } 586103fdfaSHaowei Wu } 596103fdfaSHaowei Wu fatalUnhandledError()60*6da3d8b1SFangrui Song[[noreturn]] void ErrorCollector::fatalUnhandledError() { 616103fdfaSHaowei Wu errs() << "Program aborted due to unhandled Error(s):\n"; 626103fdfaSHaowei Wu log(errs()); 636103fdfaSHaowei Wu errs() << "\n"; 646103fdfaSHaowei Wu abort(); 656103fdfaSHaowei Wu } 66