|  | //===--- PathDiagnostic.cpp - Path-Specific Diagnostic Handling -*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | //  This file defines the PathDiagnostic-related interfaces. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "clang/Analysis/PathDiagnostic.h" | 
|  | #include <sstream> | 
|  |  | 
|  | using namespace clang; | 
|  |  | 
|  | PathDiagnostic::~PathDiagnostic() { | 
|  | for (iterator I = begin(), E = end(); I != E; ++I) delete &*I; | 
|  | } | 
|  |  | 
|  | void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags, | 
|  | Diagnostic::Level DiagLevel, | 
|  | FullSourceLoc Pos, | 
|  | diag::kind ID, | 
|  | const std::string *Strs, | 
|  | unsigned NumStrs, | 
|  | const SourceRange *Ranges, | 
|  | unsigned NumRanges) { | 
|  |  | 
|  | // Create a PathDiagnostic with a single piece. | 
|  |  | 
|  | PathDiagnostic D; | 
|  |  | 
|  | // Ripped from TextDiagnostics::FormatDiagnostic.  Perhaps we should | 
|  | // centralize it somewhere? | 
|  |  | 
|  | std::ostringstream os; | 
|  |  | 
|  | switch (DiagLevel) { | 
|  | default: assert(0 && "Unknown diagnostic type!"); | 
|  | case Diagnostic::Note:    os << "note: "; break; | 
|  | case Diagnostic::Warning: os << "warning: "; break; | 
|  | case Diagnostic::Error:   os << "error: "; break; | 
|  | case Diagnostic::Fatal:   os << "fatal error: "; break; | 
|  | break; | 
|  | } | 
|  |  | 
|  | std::string Msg = Diags.getDescription(ID); | 
|  |  | 
|  | for (unsigned i = 0; i < Msg.size() - 1; ++i) { | 
|  | if (Msg[i] == '%' && isdigit(Msg[i + 1])) { | 
|  | unsigned StrNo = Msg[i + 1] - '0'; | 
|  | Msg = std::string(Msg.begin(), Msg.begin() + i) + | 
|  | (StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") + | 
|  | std::string(Msg.begin() + i + 2, Msg.end()); | 
|  | } | 
|  | } | 
|  |  | 
|  | os << Msg; | 
|  |  | 
|  | PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, os.str()); | 
|  |  | 
|  | while (NumRanges) { | 
|  | P->addRange(*Ranges); | 
|  | --NumRanges; | 
|  | ++Ranges; | 
|  | } | 
|  |  | 
|  | D.push_front(P); | 
|  |  | 
|  | HandlePathDiagnostic(D); | 
|  | } |