15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics ---------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This is a concrete diagnostic client, which buffers the diagnostic messages. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 14e1bd4e6d7c5b13462f83245865f7d9e9b6ea8486Daniel Dunbar#include "clang/Frontend/TextDiagnosticBuffer.h" 15f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner#include "llvm/ADT/SmallString.h" 16548f6c8e8010b181cb151df92f0a989363cb993eDavid Blaikie#include "llvm/Support/ErrorHandling.h" 175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1994b1dd2368dc9eeedf2794db654deae225fac763Douglas Gregor/// HandleDiagnostic - Store the errors, warnings, and notes that are 2094b1dd2368dc9eeedf2794db654deae225fac763Douglas Gregor/// reported. 211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 22d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikievoid TextDiagnosticBuffer::HandleDiagnostic(DiagnosticsEngine::Level Level, 2340847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie const Diagnostic &Info) { 24f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis // Default implementation (Warnings/errors count). 2578ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer::HandleDiagnostic(Level, Info); 26f2224d89a6ae65a3839529e26d0f6d025d83d6bbArgyrios Kyrtzidis 27f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<100> Buf; 284cbe3b64be7b1b312e4e555e8c93ef8e5bd3a820Daniel Dunbar Info.FormatDiagnostic(Buf); 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Level) { 30b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable( 31b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie "Diagnostic not handled during diagnostic buffering!"); 32d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::Note: 334cbe3b64be7b1b312e4e555e8c93ef8e5bd3a820Daniel Dunbar Notes.push_back(std::make_pair(Info.getLocation(), Buf.str())); 34233f74b29b2864d5984e13f3ae10a21404ef82e8Douglas Gregor break; 35d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::Warning: 364cbe3b64be7b1b312e4e555e8c93ef8e5bd3a820Daniel Dunbar Warnings.push_back(std::make_pair(Info.getLocation(), Buf.str())); 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 38d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::Error: 39d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::Fatal: 404cbe3b64be7b1b312e4e555e8c93ef8e5bd3a820Daniel Dunbar Errors.push_back(std::make_pair(Info.getLocation(), Buf.str())); 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 44c238955f09f3bce9386e6553d5d12f79e8cc2b08Daniel Dunbar 450f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer/// \brief Escape diagnostic texts to avoid problems when they are fed into the 460f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer/// diagnostic formatter a second time. 470f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramerstatic StringRef escapeDiag(StringRef Str, SmallVectorImpl<char> &Buf) { 480f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer size_t Pos = Str.find('%'); 490f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer if (Pos == StringRef::npos) 500f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer return Str; 510f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer 520f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer // We found a '%'. Replace this and all following '%' with '%%'. 530f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer Buf.clear(); 540f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer Buf.append(Str.data(), Str.data() + Pos); 550f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer for (size_t I = Pos, E = Str.size(); I != E; ++I) { 560f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer if (Str[I] == '%') 570f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer Buf.push_back('%'); 580f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer Buf.push_back(Str[I]); 590f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer } 600f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer 610f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer return StringRef(Buf.data(), Buf.size()); 620f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer} 630f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer 64d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikievoid TextDiagnosticBuffer::FlushDiagnostics(DiagnosticsEngine &Diags) const { 650f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer SmallVector<char, 64> Buf; 66c238955f09f3bce9386e6553d5d12f79e8cc2b08Daniel Dunbar // FIXME: Flush the diagnostics in order. 67c238955f09f3bce9386e6553d5d12f79e8cc2b08Daniel Dunbar for (const_iterator it = err_begin(), ie = err_end(); it != ie; ++it) 68d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, 690f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer escapeDiag(it->second, Buf))); 70c238955f09f3bce9386e6553d5d12f79e8cc2b08Daniel Dunbar for (const_iterator it = warn_begin(), ie = warn_end(); it != ie; ++it) 71d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Warning, 720f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer escapeDiag(it->second, Buf))); 73c238955f09f3bce9386e6553d5d12f79e8cc2b08Daniel Dunbar for (const_iterator it = note_begin(), ie = note_end(); it != ie; ++it) 74d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Note, 750f584640dce8f9d10e802b1e323a594f7850a465Benjamin Kramer escapeDiag(it->second, Buf))); 76c238955f09f3bce9386e6553d5d12f79e8cc2b08Daniel Dunbar} 77aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor 78