2009-06-21 11:36:54 +08:00
|
|
|
//===- SourceMgr.cpp - Manager for Simple Source Buffers & Diagnostics ----===//
|
2009-03-13 15:05:43 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2009-03-13 15:05:43 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2009-06-21 11:36:54 +08:00
|
|
|
// This file implements the SourceMgr class. This class is used as a simple
|
|
|
|
// substrate for diagnostics, #include handling, and other low level things for
|
|
|
|
// simple parsers.
|
2009-03-13 15:05:43 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/Support/SourceMgr.h"
|
2017-02-16 06:17:02 +08:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
2016-08-12 08:18:03 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2017-02-16 06:17:02 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/Twine.h"
|
2017-02-16 06:17:02 +08:00
|
|
|
#include "llvm/Support/ErrorOr.h"
|
2013-01-11 02:50:15 +08:00
|
|
|
#include "llvm/Support/Locale.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
2014-05-16 21:16:30 +08:00
|
|
|
#include "llvm/Support/Path.h"
|
2017-02-16 06:17:02 +08:00
|
|
|
#include "llvm/Support/SMLoc.h"
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
#include "llvm/Support/WithColor.h"
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2017-02-16 06:17:02 +08:00
|
|
|
#include <algorithm>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstddef>
|
[Support] Make line-number cache robust against access patterns.
Summary:
The LLVM SourceMgr class (which is used indirectly by Swift, though not Clang)
has a routine for looking up line numbers of SMLocs. This routine uses a
shared, special-purpose cache that handles exactly one access pattern
efficiently: looking up the line number of an SMLoc that points into the same
buffer as the last query made to the SourceMgr, at a location in the buffer at
or ahead of the last query.
When this works it's fine, but when it fails it's catastrophic for performancer:
one recent out-of-order access from a Swift utility routine ran for tens of
seconds, spending 99% of its time repeatedly scanning buffers for '\n'.
This change removes the shared cache from the SourceMgr and installs a new
cache in each SrcBuffer. The per-SrcBuffer caches are also "full", in the sense
that rather than caching a single last-query pointer, they cache _all_ the
line-ending offsets, in a binary-searchable array, such that once it's
populated (on first access), all subsequent access patterns run at the same
speed.
Performance measurements I've done show this is actually a little bit faster on
real codebases (though only a couple fractions of a percent). Memory usage is
up by a few tens to hundreds of bytes per SrcBuffer that has a line lookup done
on it; I've attempted to minimize this by using dynamic selection of integer
sized when storing offset arrays. But the main motive here is to
make-impossible the cases we don't always see, that show up by surprise when
there is an out-of-order access pattern.
Reviewers: jordan_rose
Reviewed By: jordan_rose
Subscribers: probinson, llvm-commits
Differential Revision: https://reviews.llvm.org/D45003
llvm-svn: 329470
2018-04-07 08:44:02 +08:00
|
|
|
#include <limits>
|
2017-02-16 06:17:02 +08:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
#include <utility>
|
|
|
|
|
2009-03-13 15:05:43 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2013-01-11 02:50:15 +08:00
|
|
|
static const size_t TabStop = 8;
|
|
|
|
|
2014-07-09 16:30:15 +08:00
|
|
|
unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
|
|
|
|
SMLoc IncludeLoc,
|
|
|
|
std::string &IncludedFile) {
|
2011-06-01 21:10:15 +08:00
|
|
|
IncludedFile = Filename;
|
2014-07-07 01:43:13 +08:00
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> NewBufOrErr =
|
2014-11-06 09:13:27 +08:00
|
|
|
MemoryBuffer::getFile(IncludedFile);
|
2009-06-21 13:06:04 +08:00
|
|
|
|
|
|
|
// If the file didn't exist directly, see if it's in an include path.
|
2014-07-07 01:43:13 +08:00
|
|
|
for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
|
|
|
|
++i) {
|
|
|
|
IncludedFile =
|
|
|
|
IncludeDirectories[i] + sys::path::get_separator().data() + Filename;
|
2014-11-06 09:13:27 +08:00
|
|
|
NewBufOrErr = MemoryBuffer::getFile(IncludedFile);
|
2009-06-21 13:06:04 +08:00
|
|
|
}
|
2010-01-27 18:13:11 +08:00
|
|
|
|
2014-07-07 01:43:13 +08:00
|
|
|
if (!NewBufOrErr)
|
2014-07-06 18:33:31 +08:00
|
|
|
return 0;
|
2009-06-21 13:06:04 +08:00
|
|
|
|
2014-08-22 04:44:56 +08:00
|
|
|
return AddNewSourceBuffer(std::move(*NewBufOrErr), IncludeLoc);
|
2009-06-21 13:06:04 +08:00
|
|
|
}
|
|
|
|
|
2014-07-06 18:33:31 +08:00
|
|
|
unsigned SourceMgr::FindBufferContainingLoc(SMLoc Loc) const {
|
2009-03-13 15:05:43 +08:00
|
|
|
for (unsigned i = 0, e = Buffers.size(); i != e; ++i)
|
2009-03-14 00:01:53 +08:00
|
|
|
if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
|
2009-03-19 04:36:45 +08:00
|
|
|
// Use <= here so that a pointer to the null at the end of the buffer
|
|
|
|
// is included as part of the buffer.
|
|
|
|
Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
|
2014-07-06 18:33:31 +08:00
|
|
|
return i + 1;
|
|
|
|
return 0;
|
2009-03-13 15:05:43 +08:00
|
|
|
}
|
|
|
|
|
[Support] Make line-number cache robust against access patterns.
Summary:
The LLVM SourceMgr class (which is used indirectly by Swift, though not Clang)
has a routine for looking up line numbers of SMLocs. This routine uses a
shared, special-purpose cache that handles exactly one access pattern
efficiently: looking up the line number of an SMLoc that points into the same
buffer as the last query made to the SourceMgr, at a location in the buffer at
or ahead of the last query.
When this works it's fine, but when it fails it's catastrophic for performancer:
one recent out-of-order access from a Swift utility routine ran for tens of
seconds, spending 99% of its time repeatedly scanning buffers for '\n'.
This change removes the shared cache from the SourceMgr and installs a new
cache in each SrcBuffer. The per-SrcBuffer caches are also "full", in the sense
that rather than caching a single last-query pointer, they cache _all_ the
line-ending offsets, in a binary-searchable array, such that once it's
populated (on first access), all subsequent access patterns run at the same
speed.
Performance measurements I've done show this is actually a little bit faster on
real codebases (though only a couple fractions of a percent). Memory usage is
up by a few tens to hundreds of bytes per SrcBuffer that has a line lookup done
on it; I've attempted to minimize this by using dynamic selection of integer
sized when storing offset arrays. But the main motive here is to
make-impossible the cases we don't always see, that show up by surprise when
there is an out-of-order access pattern.
Reviewers: jordan_rose
Reviewed By: jordan_rose
Subscribers: probinson, llvm-commits
Differential Revision: https://reviews.llvm.org/D45003
llvm-svn: 329470
2018-04-07 08:44:02 +08:00
|
|
|
template <typename T>
|
|
|
|
unsigned SourceMgr::SrcBuffer::getLineNumber(const char *Ptr) const {
|
|
|
|
|
|
|
|
// Ensure OffsetCache is allocated and populated with offsets of all the
|
|
|
|
// '\n' bytes.
|
|
|
|
std::vector<T> *Offsets = nullptr;
|
|
|
|
if (OffsetCache.isNull()) {
|
|
|
|
Offsets = new std::vector<T>();
|
|
|
|
OffsetCache = Offsets;
|
|
|
|
size_t Sz = Buffer->getBufferSize();
|
|
|
|
assert(Sz <= std::numeric_limits<T>::max());
|
|
|
|
StringRef S = Buffer->getBuffer();
|
|
|
|
for (size_t N = 0; N < Sz; ++N) {
|
|
|
|
if (S[N] == '\n') {
|
|
|
|
Offsets->push_back(static_cast<T>(N));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Offsets = OffsetCache.get<std::vector<T> *>();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *BufStart = Buffer->getBufferStart();
|
|
|
|
assert(Ptr >= BufStart && Ptr <= Buffer->getBufferEnd());
|
|
|
|
ptrdiff_t PtrDiff = Ptr - BufStart;
|
|
|
|
assert(PtrDiff >= 0 && static_cast<size_t>(PtrDiff) <= std::numeric_limits<T>::max());
|
|
|
|
T PtrOffset = static_cast<T>(PtrDiff);
|
|
|
|
|
2019-06-21 13:40:31 +08:00
|
|
|
// llvm::lower_bound gives the number of EOL before PtrOffset. Add 1 to get
|
|
|
|
// the line number.
|
|
|
|
return llvm::lower_bound(*Offsets, PtrOffset) - Offsets->begin() + 1;
|
[Support] Make line-number cache robust against access patterns.
Summary:
The LLVM SourceMgr class (which is used indirectly by Swift, though not Clang)
has a routine for looking up line numbers of SMLocs. This routine uses a
shared, special-purpose cache that handles exactly one access pattern
efficiently: looking up the line number of an SMLoc that points into the same
buffer as the last query made to the SourceMgr, at a location in the buffer at
or ahead of the last query.
When this works it's fine, but when it fails it's catastrophic for performancer:
one recent out-of-order access from a Swift utility routine ran for tens of
seconds, spending 99% of its time repeatedly scanning buffers for '\n'.
This change removes the shared cache from the SourceMgr and installs a new
cache in each SrcBuffer. The per-SrcBuffer caches are also "full", in the sense
that rather than caching a single last-query pointer, they cache _all_ the
line-ending offsets, in a binary-searchable array, such that once it's
populated (on first access), all subsequent access patterns run at the same
speed.
Performance measurements I've done show this is actually a little bit faster on
real codebases (though only a couple fractions of a percent). Memory usage is
up by a few tens to hundreds of bytes per SrcBuffer that has a line lookup done
on it; I've attempted to minimize this by using dynamic selection of integer
sized when storing offset arrays. But the main motive here is to
make-impossible the cases we don't always see, that show up by surprise when
there is an out-of-order access pattern.
Reviewers: jordan_rose
Reviewed By: jordan_rose
Subscribers: probinson, llvm-commits
Differential Revision: https://reviews.llvm.org/D45003
llvm-svn: 329470
2018-04-07 08:44:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&Other)
|
|
|
|
: Buffer(std::move(Other.Buffer)),
|
|
|
|
OffsetCache(Other.OffsetCache),
|
|
|
|
IncludeLoc(Other.IncludeLoc) {
|
|
|
|
Other.OffsetCache = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceMgr::SrcBuffer::~SrcBuffer() {
|
|
|
|
if (!OffsetCache.isNull()) {
|
|
|
|
if (OffsetCache.is<std::vector<uint8_t>*>())
|
|
|
|
delete OffsetCache.get<std::vector<uint8_t>*>();
|
|
|
|
else if (OffsetCache.is<std::vector<uint16_t>*>())
|
|
|
|
delete OffsetCache.get<std::vector<uint16_t>*>();
|
|
|
|
else if (OffsetCache.is<std::vector<uint32_t>*>())
|
|
|
|
delete OffsetCache.get<std::vector<uint32_t>*>();
|
|
|
|
else
|
|
|
|
delete OffsetCache.get<std::vector<uint64_t>*>();
|
|
|
|
OffsetCache = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-06 06:17:32 +08:00
|
|
|
std::pair<unsigned, unsigned>
|
2014-07-06 18:33:31 +08:00
|
|
|
SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
|
|
|
|
if (!BufferID)
|
|
|
|
BufferID = FindBufferContainingLoc(Loc);
|
|
|
|
assert(BufferID && "Invalid Location!");
|
2010-01-27 18:13:11 +08:00
|
|
|
|
[Support] Make line-number cache robust against access patterns.
Summary:
The LLVM SourceMgr class (which is used indirectly by Swift, though not Clang)
has a routine for looking up line numbers of SMLocs. This routine uses a
shared, special-purpose cache that handles exactly one access pattern
efficiently: looking up the line number of an SMLoc that points into the same
buffer as the last query made to the SourceMgr, at a location in the buffer at
or ahead of the last query.
When this works it's fine, but when it fails it's catastrophic for performancer:
one recent out-of-order access from a Swift utility routine ran for tens of
seconds, spending 99% of its time repeatedly scanning buffers for '\n'.
This change removes the shared cache from the SourceMgr and installs a new
cache in each SrcBuffer. The per-SrcBuffer caches are also "full", in the sense
that rather than caching a single last-query pointer, they cache _all_ the
line-ending offsets, in a binary-searchable array, such that once it's
populated (on first access), all subsequent access patterns run at the same
speed.
Performance measurements I've done show this is actually a little bit faster on
real codebases (though only a couple fractions of a percent). Memory usage is
up by a few tens to hundreds of bytes per SrcBuffer that has a line lookup done
on it; I've attempted to minimize this by using dynamic selection of integer
sized when storing offset arrays. But the main motive here is to
make-impossible the cases we don't always see, that show up by surprise when
there is an out-of-order access pattern.
Reviewers: jordan_rose
Reviewed By: jordan_rose
Subscribers: probinson, llvm-commits
Differential Revision: https://reviews.llvm.org/D45003
llvm-svn: 329470
2018-04-07 08:44:02 +08:00
|
|
|
auto &SB = getBufferInfo(BufferID);
|
|
|
|
const char *Ptr = Loc.getPointer();
|
|
|
|
|
|
|
|
size_t Sz = SB.Buffer->getBufferSize();
|
|
|
|
unsigned LineNo;
|
|
|
|
if (Sz <= std::numeric_limits<uint8_t>::max())
|
|
|
|
LineNo = SB.getLineNumber<uint8_t>(Ptr);
|
|
|
|
else if (Sz <= std::numeric_limits<uint16_t>::max())
|
|
|
|
LineNo = SB.getLineNumber<uint16_t>(Ptr);
|
|
|
|
else if (Sz <= std::numeric_limits<uint32_t>::max())
|
|
|
|
LineNo = SB.getLineNumber<uint32_t>(Ptr);
|
|
|
|
else
|
|
|
|
LineNo = SB.getLineNumber<uint64_t>(Ptr);
|
|
|
|
|
|
|
|
const char *BufStart = SB.Buffer->getBufferStart();
|
2012-05-06 06:17:32 +08:00
|
|
|
size_t NewlineOffs = StringRef(BufStart, Ptr-BufStart).find_last_of("\n\r");
|
2012-05-08 02:12:42 +08:00
|
|
|
if (NewlineOffs == StringRef::npos) NewlineOffs = ~(size_t)0;
|
2012-05-06 06:17:32 +08:00
|
|
|
return std::make_pair(LineNo, Ptr-BufStart-NewlineOffs);
|
2009-03-13 15:05:43 +08:00
|
|
|
}
|
|
|
|
|
2009-07-03 06:24:20 +08:00
|
|
|
void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
|
2009-06-21 11:39:35 +08:00
|
|
|
if (IncludeLoc == SMLoc()) return; // Top of stack.
|
2010-01-27 18:13:11 +08:00
|
|
|
|
2014-07-06 18:33:31 +08:00
|
|
|
unsigned CurBuf = FindBufferContainingLoc(IncludeLoc);
|
|
|
|
assert(CurBuf && "Invalid or unspecified location!");
|
2009-03-13 15:05:43 +08:00
|
|
|
|
2009-07-03 06:24:20 +08:00
|
|
|
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
|
2010-01-27 18:13:11 +08:00
|
|
|
|
2009-07-03 06:24:20 +08:00
|
|
|
OS << "Included from "
|
|
|
|
<< getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
|
|
|
|
<< ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
|
2009-03-13 15:05:43 +08:00
|
|
|
}
|
|
|
|
|
2011-10-16 13:43:57 +08:00
|
|
|
SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
|
2011-10-16 13:47:55 +08:00
|
|
|
const Twine &Msg,
|
2013-01-11 02:50:15 +08:00
|
|
|
ArrayRef<SMRange> Ranges,
|
|
|
|
ArrayRef<SMFixIt> FixIts) const {
|
2009-03-13 15:05:43 +08:00
|
|
|
// First thing to do: find the current buffer containing the specified
|
2012-05-07 00:20:49 +08:00
|
|
|
// location to pull out the source line.
|
2011-10-16 12:47:35 +08:00
|
|
|
SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges;
|
2012-05-07 00:20:49 +08:00
|
|
|
std::pair<unsigned, unsigned> LineAndCol;
|
2016-10-02 00:38:28 +08:00
|
|
|
StringRef BufferID = "<unknown>";
|
2012-05-07 00:20:49 +08:00
|
|
|
std::string LineStr;
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2012-05-07 00:20:49 +08:00
|
|
|
if (Loc.isValid()) {
|
2014-07-06 18:33:31 +08:00
|
|
|
unsigned CurBuf = FindBufferContainingLoc(Loc);
|
|
|
|
assert(CurBuf && "Invalid or unspecified location!");
|
2012-05-07 00:20:49 +08:00
|
|
|
|
2014-06-25 08:41:15 +08:00
|
|
|
const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf);
|
2012-05-07 00:20:49 +08:00
|
|
|
BufferID = CurMB->getBufferIdentifier();
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2012-05-07 00:20:49 +08:00
|
|
|
// Scan backward to find the start of the line.
|
|
|
|
const char *LineStart = Loc.getPointer();
|
|
|
|
const char *BufStart = CurMB->getBufferStart();
|
|
|
|
while (LineStart != BufStart && LineStart[-1] != '\n' &&
|
|
|
|
LineStart[-1] != '\r')
|
|
|
|
--LineStart;
|
|
|
|
|
|
|
|
// Get the end of the line.
|
|
|
|
const char *LineEnd = Loc.getPointer();
|
|
|
|
const char *BufEnd = CurMB->getBufferEnd();
|
|
|
|
while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r')
|
|
|
|
++LineEnd;
|
|
|
|
LineStr = std::string(LineStart, LineEnd);
|
|
|
|
|
|
|
|
// Convert any ranges to column ranges that only intersect the line of the
|
|
|
|
// location.
|
|
|
|
for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
|
|
|
|
SMRange R = Ranges[i];
|
|
|
|
if (!R.isValid()) continue;
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2012-05-07 00:20:49 +08:00
|
|
|
// If the line doesn't contain any part of the range, then ignore it.
|
|
|
|
if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
|
|
|
|
continue;
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2012-05-07 00:20:49 +08:00
|
|
|
// Ignore pieces of the range that go onto other lines.
|
|
|
|
if (R.Start.getPointer() < LineStart)
|
|
|
|
R.Start = SMLoc::getFromPointer(LineStart);
|
|
|
|
if (R.End.getPointer() > LineEnd)
|
|
|
|
R.End = SMLoc::getFromPointer(LineEnd);
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2012-05-07 00:20:49 +08:00
|
|
|
// Translate from SMLoc ranges to column ranges.
|
2013-01-11 02:50:15 +08:00
|
|
|
// FIXME: Handle multibyte characters.
|
2012-05-07 00:20:49 +08:00
|
|
|
ColRanges.push_back(std::make_pair(R.Start.getPointer()-LineStart,
|
|
|
|
R.End.getPointer()-LineStart));
|
|
|
|
}
|
|
|
|
|
|
|
|
LineAndCol = getLineAndColumn(Loc, CurBuf);
|
2011-10-16 12:47:35 +08:00
|
|
|
}
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2012-05-07 00:20:49 +08:00
|
|
|
return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
|
2012-05-06 06:17:32 +08:00
|
|
|
LineAndCol.second-1, Kind, Msg.str(),
|
2013-01-11 02:50:15 +08:00
|
|
|
LineStr, ColRanges, FixIts);
|
2009-07-03 07:08:13 +08:00
|
|
|
}
|
|
|
|
|
2014-06-17 10:15:40 +08:00
|
|
|
void SourceMgr::PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
|
|
|
|
bool ShowColors) const {
|
2010-04-06 08:26:48 +08:00
|
|
|
// Report the message with the diagnostic handler if present.
|
|
|
|
if (DiagHandler) {
|
2011-10-16 13:43:57 +08:00
|
|
|
DiagHandler(Diagnostic, DiagContext);
|
2010-04-06 08:26:48 +08:00
|
|
|
return;
|
|
|
|
}
|
2010-12-10 01:37:32 +08:00
|
|
|
|
2014-06-17 10:15:40 +08:00
|
|
|
if (Diagnostic.getLoc().isValid()) {
|
2014-07-06 18:33:31 +08:00
|
|
|
unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc());
|
|
|
|
assert(CurBuf && "Invalid or unspecified location!");
|
2012-05-07 00:20:49 +08:00
|
|
|
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
|
|
|
|
}
|
2009-07-03 07:08:13 +08:00
|
|
|
|
2014-04-07 12:17:22 +08:00
|
|
|
Diagnostic.print(nullptr, OS, ShowColors);
|
2009-03-13 15:05:43 +08:00
|
|
|
}
|
2009-07-03 06:24:20 +08:00
|
|
|
|
2014-06-17 10:15:40 +08:00
|
|
|
void SourceMgr::PrintMessage(raw_ostream &OS, SMLoc Loc,
|
|
|
|
SourceMgr::DiagKind Kind,
|
|
|
|
const Twine &Msg, ArrayRef<SMRange> Ranges,
|
|
|
|
ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
|
|
|
|
PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors);
|
|
|
|
}
|
|
|
|
|
2013-09-28 05:09:25 +08:00
|
|
|
void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
|
|
|
|
const Twine &Msg, ArrayRef<SMRange> Ranges,
|
|
|
|
ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
|
2017-02-16 06:17:02 +08:00
|
|
|
PrintMessage(errs(), Loc, Kind, Msg, Ranges, FixIts, ShowColors);
|
2013-09-28 05:09:25 +08:00
|
|
|
}
|
|
|
|
|
2009-07-03 06:24:20 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// SMDiagnostic Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2020-01-29 03:23:46 +08:00
|
|
|
SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line,
|
|
|
|
int Col, SourceMgr::DiagKind Kind, StringRef Msg,
|
|
|
|
StringRef LineStr,
|
|
|
|
ArrayRef<std::pair<unsigned, unsigned>> Ranges,
|
2013-01-11 02:50:15 +08:00
|
|
|
ArrayRef<SMFixIt> Hints)
|
2020-01-29 03:23:46 +08:00
|
|
|
: SM(&sm), Loc(L), Filename(std::string(FN)), LineNo(Line), ColumnNo(Col),
|
|
|
|
Kind(Kind), Message(std::string(Msg)), LineContents(std::string(LineStr)),
|
|
|
|
Ranges(Ranges.vec()), FixIts(Hints.begin(), Hints.end()) {
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 10:13:45 +08:00
|
|
|
llvm::sort(FixIts);
|
2013-01-11 02:50:15 +08:00
|
|
|
}
|
|
|
|
|
2013-02-15 20:30:38 +08:00
|
|
|
static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
|
|
|
|
ArrayRef<SMFixIt> FixIts, ArrayRef<char> SourceLine){
|
2013-01-11 02:50:15 +08:00
|
|
|
if (FixIts.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
const char *LineStart = SourceLine.begin();
|
|
|
|
const char *LineEnd = SourceLine.end();
|
|
|
|
|
|
|
|
size_t PrevHintEndCol = 0;
|
|
|
|
|
|
|
|
for (ArrayRef<SMFixIt>::iterator I = FixIts.begin(), E = FixIts.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
// If the fixit contains a newline or tab, ignore it.
|
|
|
|
if (I->getText().find_first_of("\n\r\t") != StringRef::npos)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
SMRange R = I->getRange();
|
|
|
|
|
|
|
|
// If the line doesn't contain any part of the range, then ignore it.
|
|
|
|
if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Translate from SMLoc to column.
|
|
|
|
// Ignore pieces of the range that go onto other lines.
|
|
|
|
// FIXME: Handle multibyte characters in the source line.
|
|
|
|
unsigned FirstCol;
|
|
|
|
if (R.Start.getPointer() < LineStart)
|
|
|
|
FirstCol = 0;
|
|
|
|
else
|
|
|
|
FirstCol = R.Start.getPointer() - LineStart;
|
|
|
|
|
|
|
|
// If we inserted a long previous hint, push this one forwards, and add
|
|
|
|
// an extra space to show that this is not part of the previous
|
|
|
|
// completion. This is sort of the best we can do when two hints appear
|
|
|
|
// to overlap.
|
|
|
|
//
|
|
|
|
// Note that if this hint is located immediately after the previous
|
|
|
|
// hint, no space will be added, since the location is more important.
|
|
|
|
unsigned HintCol = FirstCol;
|
|
|
|
if (HintCol < PrevHintEndCol)
|
|
|
|
HintCol = PrevHintEndCol + 1;
|
|
|
|
|
|
|
|
// FIXME: This assertion is intended to catch unintended use of multibyte
|
|
|
|
// characters in fixits. If we decide to do this, we'll have to track
|
|
|
|
// separate byte widths for the source and fixit lines.
|
2017-02-16 06:17:02 +08:00
|
|
|
assert((size_t)sys::locale::columnWidth(I->getText()) ==
|
2013-01-11 02:50:15 +08:00
|
|
|
I->getText().size());
|
|
|
|
|
|
|
|
// This relies on one byte per column in our fixit hints.
|
|
|
|
unsigned LastColumnModified = HintCol + I->getText().size();
|
|
|
|
if (LastColumnModified > FixItLine.size())
|
|
|
|
FixItLine.resize(LastColumnModified, ' ');
|
|
|
|
|
|
|
|
std::copy(I->getText().begin(), I->getText().end(),
|
|
|
|
FixItLine.begin() + HintCol);
|
|
|
|
|
|
|
|
PrevHintEndCol = LastColumnModified;
|
|
|
|
|
|
|
|
// For replacements, mark the removal range with '~'.
|
|
|
|
// FIXME: Handle multibyte characters in the source line.
|
|
|
|
unsigned LastCol;
|
|
|
|
if (R.End.getPointer() >= LineEnd)
|
|
|
|
LastCol = LineEnd - LineStart;
|
|
|
|
else
|
|
|
|
LastCol = R.End.getPointer() - LineStart;
|
|
|
|
|
|
|
|
std::fill(&CaretLine[FirstCol], &CaretLine[LastCol], '~');
|
|
|
|
}
|
2011-10-16 13:43:57 +08:00
|
|
|
}
|
2011-10-16 12:47:35 +08:00
|
|
|
|
2013-01-11 02:50:15 +08:00
|
|
|
static void printSourceLine(raw_ostream &S, StringRef LineContents) {
|
|
|
|
// Print out the source line one character at a time, so we can expand tabs.
|
|
|
|
for (unsigned i = 0, e = LineContents.size(), OutCol = 0; i != e; ++i) {
|
[Windows] Convert from UTF-8 to UTF-16 when writing to a Windows console
Summary:
Calling WriteConsoleW is the most reliable way to print Unicode
characters to a Windows console.
If binary data gets printed to the console, attempting to re-encode it
shouldn't be a problem, since garbage in can produce garbage out.
This breaks printing strings in the local codepage, which WriteConsoleA
knows how to handle. For example, this can happen when user source code
is encoded with the local codepage, and an LLVM tool quotes it while
emitting a caret diagnostic. This is unfortunate, but well-behaved tools
should validate that their input is UTF-8 and escape non-UTF-8
characters before sending them to raw_fd_ostream. Clang already does
this, but not all LLVM tools do this.
One drawback to the current implementation is printing a string a byte
at a time doesn't work. Consider this LLVM code:
for (char C : MyStr) outs() << C;
Because outs() is now unbuffered, we wil try to convert each byte to
UTF-16, which will fail. However, this already didn't work, so I think
we may as well update callers that do that as we find them to print
complete portions of strings. You can see a real example of this in my
patch to SourceMgr.cpp
Fixes PR38669 and PR36267.
Reviewers: zturner, efriedma
Subscribers: llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D51558
llvm-svn: 341433
2018-09-05 08:08:56 +08:00
|
|
|
size_t NextTab = LineContents.find('\t', i);
|
|
|
|
// If there were no tabs left, print the rest, we are done.
|
|
|
|
if (NextTab == StringRef::npos) {
|
|
|
|
S << LineContents.drop_front(i);
|
|
|
|
break;
|
2013-01-11 02:50:15 +08:00
|
|
|
}
|
|
|
|
|
[Windows] Convert from UTF-8 to UTF-16 when writing to a Windows console
Summary:
Calling WriteConsoleW is the most reliable way to print Unicode
characters to a Windows console.
If binary data gets printed to the console, attempting to re-encode it
shouldn't be a problem, since garbage in can produce garbage out.
This breaks printing strings in the local codepage, which WriteConsoleA
knows how to handle. For example, this can happen when user source code
is encoded with the local codepage, and an LLVM tool quotes it while
emitting a caret diagnostic. This is unfortunate, but well-behaved tools
should validate that their input is UTF-8 and escape non-UTF-8
characters before sending them to raw_fd_ostream. Clang already does
this, but not all LLVM tools do this.
One drawback to the current implementation is printing a string a byte
at a time doesn't work. Consider this LLVM code:
for (char C : MyStr) outs() << C;
Because outs() is now unbuffered, we wil try to convert each byte to
UTF-16, which will fail. However, this already didn't work, so I think
we may as well update callers that do that as we find them to print
complete portions of strings. You can see a real example of this in my
patch to SourceMgr.cpp
Fixes PR38669 and PR36267.
Reviewers: zturner, efriedma
Subscribers: llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D51558
llvm-svn: 341433
2018-09-05 08:08:56 +08:00
|
|
|
// Otherwise, print from i to NextTab.
|
|
|
|
S << LineContents.slice(i, NextTab);
|
|
|
|
OutCol += NextTab - i;
|
|
|
|
i = NextTab;
|
|
|
|
|
2013-01-11 02:50:15 +08:00
|
|
|
// If we have a tab, emit at least one space, then round up to 8 columns.
|
|
|
|
do {
|
|
|
|
S << ' ';
|
|
|
|
++OutCol;
|
|
|
|
} while ((OutCol % TabStop) != 0);
|
|
|
|
}
|
|
|
|
S << '\n';
|
|
|
|
}
|
2011-10-16 12:47:35 +08:00
|
|
|
|
2013-01-11 10:37:55 +08:00
|
|
|
static bool isNonASCII(char c) {
|
|
|
|
return c & 0x80;
|
|
|
|
}
|
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
void SMDiagnostic::print(const char *ProgName, raw_ostream &OS,
|
|
|
|
bool ShowColors, bool ShowKindLabel) const {
|
|
|
|
{
|
|
|
|
WithColor S(OS, raw_ostream::SAVEDCOLOR, true, false, !ShowColors);
|
2012-04-19 03:04:15 +08:00
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
if (ProgName && ProgName[0])
|
|
|
|
S << ProgName << ": ";
|
2012-04-19 03:04:15 +08:00
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
if (!Filename.empty()) {
|
|
|
|
if (Filename == "-")
|
|
|
|
S << "<stdin>";
|
|
|
|
else
|
|
|
|
S << Filename;
|
2009-07-03 06:24:20 +08:00
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
if (LineNo != -1) {
|
|
|
|
S << ':' << LineNo;
|
|
|
|
if (ColumnNo != -1)
|
|
|
|
S << ':' << (ColumnNo + 1);
|
|
|
|
}
|
|
|
|
S << ": ";
|
2010-01-21 18:13:27 +08:00
|
|
|
}
|
2009-07-03 06:24:20 +08:00
|
|
|
}
|
2010-01-27 18:13:11 +08:00
|
|
|
|
2015-06-16 04:30:22 +08:00
|
|
|
if (ShowKindLabel) {
|
|
|
|
switch (Kind) {
|
|
|
|
case SourceMgr::DK_Error:
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
WithColor::error(OS, "", !ShowColors);
|
2015-06-16 04:30:22 +08:00
|
|
|
break;
|
|
|
|
case SourceMgr::DK_Warning:
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
WithColor::warning(OS, "", !ShowColors);
|
2015-06-16 04:30:22 +08:00
|
|
|
break;
|
|
|
|
case SourceMgr::DK_Note:
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
WithColor::note(OS, "", !ShowColors);
|
2015-06-16 04:30:22 +08:00
|
|
|
break;
|
2017-10-13 07:56:02 +08:00
|
|
|
case SourceMgr::DK_Remark:
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
WithColor::remark(OS, "", !ShowColors);
|
2017-10-13 07:56:02 +08:00
|
|
|
break;
|
2015-06-16 04:30:22 +08:00
|
|
|
}
|
2012-04-19 03:04:15 +08:00
|
|
|
}
|
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
WithColor(OS, raw_ostream::SAVEDCOLOR, true, false, !ShowColors)
|
|
|
|
<< Message << '\n';
|
2012-04-19 03:04:15 +08:00
|
|
|
|
2011-10-16 13:47:55 +08:00
|
|
|
if (LineNo == -1 || ColumnNo == -1)
|
2011-10-16 12:47:35 +08:00
|
|
|
return;
|
2010-01-27 18:13:11 +08:00
|
|
|
|
2013-01-11 10:37:55 +08:00
|
|
|
// FIXME: If there are multibyte or multi-column characters in the source, all
|
|
|
|
// our ranges will be wrong. To do this properly, we'll need a byte-to-column
|
|
|
|
// map like Clang's TextDiagnostic. For now, we'll just handle tabs by
|
|
|
|
// expanding them later, and bail out rather than show incorrect ranges and
|
|
|
|
// misaligned fixits for any other odd characters.
|
2016-08-12 08:18:03 +08:00
|
|
|
if (find_if(LineContents, isNonASCII) != LineContents.end()) {
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
printSourceLine(OS, LineContents);
|
2013-01-11 02:50:15 +08:00
|
|
|
return;
|
|
|
|
}
|
2013-01-11 10:37:55 +08:00
|
|
|
size_t NumColumns = LineContents.size();
|
2013-01-11 02:50:15 +08:00
|
|
|
|
2011-10-16 12:47:35 +08:00
|
|
|
// Build the line with the caret and ranges.
|
2013-01-11 02:50:15 +08:00
|
|
|
std::string CaretLine(NumColumns+1, ' ');
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2011-10-16 12:47:35 +08:00
|
|
|
// Expand any ranges.
|
|
|
|
for (unsigned r = 0, e = Ranges.size(); r != e; ++r) {
|
|
|
|
std::pair<unsigned, unsigned> R = Ranges[r];
|
2013-01-11 02:50:15 +08:00
|
|
|
std::fill(&CaretLine[R.first],
|
|
|
|
&CaretLine[std::min((size_t)R.second, CaretLine.size())],
|
|
|
|
'~');
|
2011-10-16 12:47:35 +08:00
|
|
|
}
|
2013-01-11 02:50:15 +08:00
|
|
|
|
|
|
|
// Add any fix-its.
|
|
|
|
// FIXME: Find the beginning of the line properly for multibyte characters.
|
|
|
|
std::string FixItInsertionLine;
|
|
|
|
buildFixItLine(CaretLine, FixItInsertionLine, FixIts,
|
|
|
|
makeArrayRef(Loc.getPointer() - ColumnNo,
|
|
|
|
LineContents.size()));
|
|
|
|
|
2011-10-16 12:47:35 +08:00
|
|
|
// Finally, plop on the caret.
|
2013-01-11 02:50:15 +08:00
|
|
|
if (unsigned(ColumnNo) <= NumColumns)
|
2011-10-16 12:47:35 +08:00
|
|
|
CaretLine[ColumnNo] = '^';
|
2018-07-31 03:41:25 +08:00
|
|
|
else
|
2013-01-11 02:50:15 +08:00
|
|
|
CaretLine[NumColumns] = '^';
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2011-10-16 12:47:35 +08:00
|
|
|
// ... and remove trailing whitespace so the output doesn't wrap for it. We
|
|
|
|
// know that the line isn't completely empty because it has the caret in it at
|
|
|
|
// least.
|
|
|
|
CaretLine.erase(CaretLine.find_last_not_of(' ')+1);
|
2018-07-31 03:41:25 +08:00
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
printSourceLine(OS, LineContents);
|
2011-10-16 12:47:35 +08:00
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
{
|
|
|
|
WithColor S(OS, raw_ostream::GREEN, true, false, !ShowColors);
|
2012-04-19 03:04:15 +08:00
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
// Print out the caret line, matching tabs in the source line.
|
|
|
|
for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
|
|
|
|
if (i >= LineContents.size() || LineContents[i] != '\t') {
|
|
|
|
S << CaretLine[i];
|
|
|
|
++OutCol;
|
|
|
|
continue;
|
|
|
|
}
|
2018-10-23 02:51:29 +08:00
|
|
|
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
// Okay, we have a tab. Insert the appropriate number of characters.
|
|
|
|
do {
|
|
|
|
S << CaretLine[i];
|
|
|
|
++OutCol;
|
|
|
|
} while ((OutCol % TabStop) != 0);
|
|
|
|
}
|
|
|
|
S << '\n';
|
2009-07-03 06:24:20 +08:00
|
|
|
}
|
2013-01-11 02:50:15 +08:00
|
|
|
|
|
|
|
// Print out the replacement line, matching tabs in the source line.
|
|
|
|
if (FixItInsertionLine.empty())
|
|
|
|
return;
|
2018-07-31 03:41:25 +08:00
|
|
|
|
2013-09-28 05:24:36 +08:00
|
|
|
for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
|
2013-01-11 02:50:15 +08:00
|
|
|
if (i >= LineContents.size() || LineContents[i] != '\t') {
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
OS << FixItInsertionLine[i];
|
2013-01-11 02:50:15 +08:00
|
|
|
++OutCol;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Okay, we have a tab. Insert the appropriate number of characters.
|
|
|
|
do {
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
OS << FixItInsertionLine[i];
|
2013-01-11 02:50:15 +08:00
|
|
|
// FIXME: This is trying not to break up replacements, but then to re-sync
|
|
|
|
// with the tabs between replacements. This will fail, though, if two
|
|
|
|
// fix-it replacements are exactly adjacent, or if a fix-it contains a
|
|
|
|
// space. Really we should be precomputing column widths, which we'll
|
|
|
|
// need anyway for multibyte chars.
|
|
|
|
if (FixItInsertionLine[i] != ' ')
|
|
|
|
++i;
|
|
|
|
++OutCol;
|
|
|
|
} while (((OutCol % TabStop) != 0) && i != e);
|
|
|
|
}
|
[SourceMgr][FileCheck] Obey -color by extending WithColor
(Relands r344930, reverted in r344935, and now hopefully fixed for
Windows.)
While this change specifically targets FileCheck, it affects any tool
using the same SourceMgr facilities.
Previously, -color was documented in FileCheck's -help output, but
-color had no effect. Now, -color obeys its documentation: it forces
colors to be used in FileCheck diagnostics even when stderr is not a
terminal.
-color is especially helpful when combined with FileCheck's -v, which
can produce a long series of diagnostics that you might wish to pipe
to a pager, such as less -R. The WithColor extensions here will also
help to clean up color usage in FileCheck's annotated dump of input,
which is proposed in D52999.
Reviewed By: JDevlieghere, zturner
Differential Revision: https://reviews.llvm.org/D53419
llvm-svn: 345202
2018-10-25 05:46:42 +08:00
|
|
|
OS << '\n';
|
2009-07-03 06:24:20 +08:00
|
|
|
}
|