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