forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			118 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===- Error.cpp ----------------------------------------------------------===//
 | |
| //
 | |
| //                             The LLVM Linker
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "Error.h"
 | |
| #include "Config.h"
 | |
| 
 | |
| #include "llvm/ADT/Twine.h"
 | |
| #include "llvm/Support/Error.h"
 | |
| #include "llvm/Support/ManagedStatic.h"
 | |
| #include "llvm/Support/raw_ostream.h"
 | |
| #include <mutex>
 | |
| 
 | |
| #if !defined(_MSC_VER) && !defined(__MINGW32__)
 | |
| #include <unistd.h>
 | |
| #endif
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| using namespace lld;
 | |
| using namespace lld::elf;
 | |
| 
 | |
| uint64_t elf::ErrorCount;
 | |
| raw_ostream *elf::ErrorOS;
 | |
| StringRef elf::Argv0;
 | |
| 
 | |
| // The functions defined in this file can be called from multiple threads,
 | |
| // but outs() or errs() are not thread-safe. We protect them using a mutex.
 | |
| static std::mutex Mu;
 | |
| 
 | |
| // Prints "\n" or does nothing, depending on Msg contents of
 | |
| // the previous call of this function.
 | |
| static void newline(const Twine &Msg) {
 | |
|   // True if the previous error message contained "\n".
 | |
|   // We want to separate multi-line error messages with a newline.
 | |
|   static bool Flag;
 | |
| 
 | |
|   if (Flag)
 | |
|     *ErrorOS << "\n";
 | |
|   Flag = (StringRef(Msg.str()).find('\n') != StringRef::npos);
 | |
| }
 | |
| 
 | |
| static void print(StringRef S, raw_ostream::Colors C) {
 | |
|   *ErrorOS << Argv0 + ": ";
 | |
|   if (Config->ColorDiagnostics) {
 | |
|     ErrorOS->changeColor(C, true);
 | |
|     *ErrorOS << S;
 | |
|     ErrorOS->resetColor();
 | |
|   } else {
 | |
|     *ErrorOS << S;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void elf::log(const Twine &Msg) {
 | |
|   if (Config->Verbose) {
 | |
|     std::lock_guard<std::mutex> Lock(Mu);
 | |
|     outs() << Argv0 << ": " << Msg << "\n";
 | |
|     outs().flush();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void elf::message(const Twine &Msg) {
 | |
|   std::lock_guard<std::mutex> Lock(Mu);
 | |
|   outs() << Msg << "\n";
 | |
|   outs().flush();
 | |
| }
 | |
| 
 | |
| void elf::warn(const Twine &Msg) {
 | |
|   if (Config->FatalWarnings) {
 | |
|     error(Msg);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   std::lock_guard<std::mutex> Lock(Mu);
 | |
|   newline(Msg);
 | |
|   print("warning: ", raw_ostream::MAGENTA);
 | |
|   *ErrorOS << Msg << "\n";
 | |
| }
 | |
| 
 | |
| void elf::error(const Twine &Msg) {
 | |
|   std::lock_guard<std::mutex> Lock(Mu);
 | |
|   newline(Msg);
 | |
| 
 | |
|   if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
 | |
|     print("error: ", raw_ostream::RED);
 | |
|     *ErrorOS << Msg << "\n";
 | |
|   } else if (ErrorCount == Config->ErrorLimit) {
 | |
|     print("error: ", raw_ostream::RED);
 | |
|     *ErrorOS << "too many errors emitted, stopping now"
 | |
|              << " (use -error-limit=0 to see all errors)\n";
 | |
|     if (Config->ExitEarly)
 | |
|       exitLld(1);
 | |
|   }
 | |
| 
 | |
|   ++ErrorCount;
 | |
| }
 | |
| 
 | |
| void elf::exitLld(int Val) {
 | |
|   // Dealloc/destroy ManagedStatic variables before calling
 | |
|   // _exit(). In a non-LTO build, this is a nop. In an LTO
 | |
|   // build allows us to get the output of -time-passes.
 | |
|   llvm_shutdown();
 | |
| 
 | |
|   outs().flush();
 | |
|   errs().flush();
 | |
|   _exit(Val);
 | |
| }
 | |
| 
 | |
| void elf::fatal(const Twine &Msg) {
 | |
|   error(Msg);
 | |
|   exitLld(1);
 | |
| }
 |