//===--- TextDiagnosticPrinter.cpp - Diagnostic Printer -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This diagnostic client prints out their diagnostic messages.
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
using namespace clang;
static const enum raw_ostream::Colors noteColor =
raw_ostream::BLACK;
static const enum raw_ostream::Colors fixitColor =
raw_ostream::GREEN;
static const enum raw_ostream::Colors caretColor =
raw_ostream::GREEN;
static const enum raw_ostream::Colors warningColor =
raw_ostream::MAGENTA;
static const enum raw_ostream::Colors errorColor = raw_ostream::RED;
static const enum raw_ostream::Colors fatalColor = raw_ostream::RED;
// Used for changing only the bold attribute.
static const enum raw_ostream::Colors savedColor =
raw_ostream::SAVEDCOLOR;
/// \brief Number of spaces to indent when word-wrapping.
const unsigned WordWrapIndentation = 6;
TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
const DiagnosticOptions &diags,
bool _OwnsOutputStream)
: OS(os), LangOpts(0), DiagOpts(&diags),
LastCaretDiagnosticWasNote(0),
OwnsOutputStream(_OwnsOutputStream) {
}
TextDiagnosticPrinter::~TextDiagnosticPrinter() {
if (OwnsOutputStream)
delete &OS;
}
/// \brief Helper to recursivly walk up the include stack and print each layer
/// on the way back down.
static void PrintIncludeStackRecursively(raw_ostream &OS,
const SourceManager &SM,
SourceLocation Loc,
bool ShowLocation) {
if (Loc.isInvalid())
return;
PresumedLoc PLoc = SM.getPresumedLoc(Loc);
if (PLoc.isInvalid())
return;
// Print out the other include frames first.
PrintIncludeStackRecursively(OS, SM, PLoc.getIncludeLoc(), ShowLocation);
if (ShowLocation)
OS << "In file included from " << PLoc.getFilename()
<< ':' << PLoc.getLine() << ":\n";
else
OS << "In included file:\n";
}
/// \brief Prints an include stack when appropriate for a particular diagnostic
/// level and location.
///
/// This routine handles all the logic of suppressing particular include stacks
/// (such as those for notes) and duplicate include stacks when repeated
/// warnings occur within the same file. It also handles the logic of
/// customizing the formatting and display of the include stack.
///
/// \param Level The diagnostic level of the message this stack pertains to.
/// \param Loc The include location of the current file (not the diagnostic
/// location).
void TextDiagnosticPrinter::PrintIncludeStack(Diagnostic::Level Level,
SourceLocation Loc,
const SourceManager &SM) {