//===----------------------------------------------------------------------===//
#include "llvm/Support/SourceMgr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Locale.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
using namespace llvm;
/// AddIncludeFile - Search for a file with the specified name in the current
/// directory or in one of the IncludeDirs. If no file is found, this returns
/// ~0, otherwise it returns the buffer ID of the stacked file.
-unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
- SMLoc IncludeLoc,
- std::string &IncludedFile) {
- OwningPtr<MemoryBuffer> NewBuf;
+size_t SourceMgr::AddIncludeFile(const std::string &Filename,
+ SMLoc IncludeLoc,
+ std::string &IncludedFile) {
+ std::unique_ptr<MemoryBuffer> NewBuf;
IncludedFile = Filename;
MemoryBuffer::getFile(IncludedFile.c_str(), NewBuf);
// If the file didn't exist directly, see if it's in an include path.
for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) {
- IncludedFile = IncludeDirectories[i] + "/" + Filename;
+ IncludedFile = IncludeDirectories[i] + sys::path::get_separator().data() + Filename;
MemoryBuffer::getFile(IncludedFile.c_str(), NewBuf);
}
- if (NewBuf == 0) return ~0U;
+ if (!NewBuf) return ~0U;
- return AddNewSourceBuffer(NewBuf.take(), IncludeLoc);
+ return AddNewSourceBuffer(NewBuf.release(), IncludeLoc);
}
if (*Ptr == '\n') ++LineNo;
// Allocate the line number cache if it doesn't exist.
- if (LineNoCache == 0)
+ if (!LineNoCache)
LineNoCache = new LineNoCacheTy();
// Update the line # cache.
LineStr, ColRanges, FixIts);
}
-void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
+void SourceMgr::PrintMessage(raw_ostream &OS, SMLoc Loc,
+ SourceMgr::DiagKind Kind,
const Twine &Msg, ArrayRef<SMRange> Ranges,
ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
SMDiagnostic Diagnostic = GetMessage(Loc, Kind, Msg, Ranges, FixIts);
return;
}
- raw_ostream &OS = errs();
-
if (Loc != SMLoc()) {
int CurBuf = FindBufferContainingLoc(Loc);
assert(CurBuf != -1 && "Invalid or unspecified location!");
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
}
- Diagnostic.print(0, OS, ShowColors);
+ Diagnostic.print(nullptr, OS, ShowColors);
+}
+
+void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
+ const Twine &Msg, ArrayRef<SMRange> Ranges,
+ ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
+ PrintMessage(llvm::errs(), Loc, Kind, Msg, Ranges, FixIts, ShowColors);
}
//===----------------------------------------------------------------------===//
std::sort(FixIts.begin(), FixIts.end());
}
-void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
- ArrayRef<SMFixIt> FixIts, ArrayRef<char> SourceLine) {
+static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
+ ArrayRef<SMFixIt> FixIts, ArrayRef<char> SourceLine){
if (FixIts.empty())
return;
S << '\n';
}
+static bool isNonASCII(char c) {
+ return c & 0x80;
+}
+
void SMDiagnostic::print(const char *ProgName, raw_ostream &S,
bool ShowColors) const {
// Display colors only if OS supports colors.
if (LineNo == -1 || ColumnNo == -1)
return;
- // FIXME: If there are multibyte 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.
- SmallString<128> PrintableLine(LineContents);
- std::replace(PrintableLine.begin(), PrintableLine.end(), '\t', ' ');
- size_t NumColumns = (size_t)llvm::sys::locale::columnWidth(PrintableLine);
- if (NumColumns != PrintableLine.size()) {
+ // 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.
+ if (std::find_if(LineContents.begin(), LineContents.end(), isNonASCII) !=
+ LineContents.end()) {
printSourceLine(S, LineContents);
return;
}
+ size_t NumColumns = LineContents.size();
// Build the line with the caret and ranges.
std::string CaretLine(NumColumns+1, ' ');
if (FixItInsertionLine.empty())
return;
- for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i != e; ++i) {
+ for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
if (i >= LineContents.size() || LineContents[i] != '\t') {
S << FixItInsertionLine[i];
++OutCol;