1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-22 12:33:33 +02:00
llvm-mirror/include/llvm/Support/SourceMgr.h
Benjamin Kramer c2de5980d3 Do a sweep over move ctors and remove those that are identical to the default.
All of these existed because MSVC 2013 was unable to synthesize default
move ctors. We recently dropped support for it so all that error-prone
boilerplate can go.

No functionality change intended.

llvm-svn: 284721
2016-10-20 12:20:28 +00:00

281 lines
9.2 KiB
C++

//===- SourceMgr.h - Manager for Source Buffers & Diagnostics ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the SMDiagnostic and SourceMgr classes. This
// provides a simple substrate for diagnostics, #include handling, and other low
// level things for simple parsers.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_SOURCEMGR_H
#define LLVM_SUPPORT_SOURCEMGR_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h"
#include <string>
namespace llvm {
class SourceMgr;
class SMDiagnostic;
class SMFixIt;
class Twine;
class raw_ostream;
/// This owns the files read by a parser, handles include stacks,
/// and handles diagnostic wrangling.
class SourceMgr {
public:
enum DiagKind {
DK_Error,
DK_Warning,
DK_Note
};
/// Clients that want to handle their own diagnostics in a custom way can
/// register a function pointer+context as a diagnostic handler.
/// It gets called each time PrintMessage is invoked.
typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
private:
struct SrcBuffer {
/// The memory buffer for the file.
std::unique_ptr<MemoryBuffer> Buffer;
/// This is the location of the parent include, or null if at the top level.
SMLoc IncludeLoc;
};
/// This is all of the buffers that we are reading from.
std::vector<SrcBuffer> Buffers;
// This is the list of directories we should search for include files in.
std::vector<std::string> IncludeDirectories;
/// This is a cache for line number queries, its implementation is really
/// private to SourceMgr.cpp.
mutable void *LineNoCache;
DiagHandlerTy DiagHandler;
void *DiagContext;
bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
SourceMgr(const SourceMgr&) = delete;
void operator=(const SourceMgr&) = delete;
public:
SourceMgr()
: LineNoCache(nullptr), DiagHandler(nullptr), DiagContext(nullptr) {}
~SourceMgr();
void setIncludeDirs(const std::vector<std::string> &Dirs) {
IncludeDirectories = Dirs;
}
/// Specify a diagnostic handler to be invoked every time PrintMessage is
/// called. \p Ctx is passed into the handler when it is invoked.
void setDiagHandler(DiagHandlerTy DH, void *Ctx = nullptr) {
DiagHandler = DH;
DiagContext = Ctx;
}
DiagHandlerTy getDiagHandler() const { return DiagHandler; }
void *getDiagContext() const { return DiagContext; }
const SrcBuffer &getBufferInfo(unsigned i) const {
assert(isValidBufferID(i));
return Buffers[i - 1];
}
const MemoryBuffer *getMemoryBuffer(unsigned i) const {
assert(isValidBufferID(i));
return Buffers[i - 1].Buffer.get();
}
unsigned getNumBuffers() const {
return Buffers.size();
}
unsigned getMainFileID() const {
assert(getNumBuffers());
return 1;
}
SMLoc getParentIncludeLoc(unsigned i) const {
assert(isValidBufferID(i));
return Buffers[i - 1].IncludeLoc;
}
/// Add a new source buffer to this source manager. This takes ownership of
/// the memory buffer.
unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = std::move(F);
NB.IncludeLoc = IncludeLoc;
Buffers.push_back(std::move(NB));
return Buffers.size();
}
/// 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. The full path to the included file can be found in
/// \p IncludedFile.
unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
std::string &IncludedFile);
/// Return the ID of the buffer containing the specified location.
///
/// 0 is returned if the buffer is not found.
unsigned FindBufferContainingLoc(SMLoc Loc) const;
/// Find the line number for the specified location in the specified file.
/// This is not a fast method.
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID = 0) const {
return getLineAndColumn(Loc, BufferID).first;
}
/// Find the line and column number for the specified location in the
/// specified file. This is not a fast method.
std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
unsigned BufferID = 0) const;
/// Emit a message about the specified location with the specified string.
///
/// \param ShowColors Display colored messages if output is a terminal and
/// the default error handler is used.
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind,
const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
ArrayRef<SMFixIt> FixIts = None,
bool ShowColors = true) const;
/// Emits a diagnostic to llvm::errs().
void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
ArrayRef<SMFixIt> FixIts = None,
bool ShowColors = true) const;
/// Emits a manually-constructed diagnostic to the given output stream.
///
/// \param ShowColors Display colored messages if output is a terminal and
/// the default error handler is used.
void PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
bool ShowColors = true) const;
/// Return an SMDiagnostic at the specified location with the specified
/// string.
///
/// \param Msg If non-null, the kind of message (e.g., "error") which is
/// prefixed to the message.
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
ArrayRef<SMFixIt> FixIts = None) const;
/// Prints the names of included files and the line of the file they were
/// included from. A diagnostic handler can use this before printing its
/// custom formatted message.
///
/// \param IncludeLoc The location of the include.
/// \param OS the raw_ostream to print on.
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
};
/// Represents a single fixit, a replacement of one range of text with another.
class SMFixIt {
SMRange Range;
std::string Text;
public:
// FIXME: Twine.str() is not very efficient.
SMFixIt(SMLoc Loc, const Twine &Insertion)
: Range(Loc, Loc), Text(Insertion.str()) {
assert(Loc.isValid());
}
// FIXME: Twine.str() is not very efficient.
SMFixIt(SMRange R, const Twine &Replacement)
: Range(R), Text(Replacement.str()) {
assert(R.isValid());
}
StringRef getText() const { return Text; }
SMRange getRange() const { return Range; }
bool operator<(const SMFixIt &Other) const {
if (Range.Start.getPointer() != Other.Range.Start.getPointer())
return Range.Start.getPointer() < Other.Range.Start.getPointer();
if (Range.End.getPointer() != Other.Range.End.getPointer())
return Range.End.getPointer() < Other.Range.End.getPointer();
return Text < Other.Text;
}
};
/// Instances of this class encapsulate one diagnostic report, allowing
/// printing to a raw_ostream as a caret diagnostic.
class SMDiagnostic {
const SourceMgr *SM;
SMLoc Loc;
std::string Filename;
int LineNo, ColumnNo;
SourceMgr::DiagKind Kind;
std::string Message, LineContents;
std::vector<std::pair<unsigned, unsigned> > Ranges;
SmallVector<SMFixIt, 4> FixIts;
public:
// Null diagnostic.
SMDiagnostic()
: SM(nullptr), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
// Diagnostic with no location (e.g. file not found, command line arg error).
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
: SM(nullptr), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
Message(Msg) {}
// Diagnostic with a location.
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,
ArrayRef<SMFixIt> FixIts = None);
const SourceMgr *getSourceMgr() const { return SM; }
SMLoc getLoc() const { return Loc; }
StringRef getFilename() const { return Filename; }
int getLineNo() const { return LineNo; }
int getColumnNo() const { return ColumnNo; }
SourceMgr::DiagKind getKind() const { return Kind; }
StringRef getMessage() const { return Message; }
StringRef getLineContents() const { return LineContents; }
ArrayRef<std::pair<unsigned, unsigned> > getRanges() const {
return Ranges;
}
void addFixIt(const SMFixIt &Hint) {
FixIts.push_back(Hint);
}
ArrayRef<SMFixIt> getFixIts() const {
return FixIts;
}
void print(const char *ProgName, raw_ostream &S, bool ShowColors = true,
bool ShowKindLabel = true) const;
};
} // end llvm namespace
#endif