#include "mlir/Support/LLVM.h"
#include "mlir/Support/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include <functional>
namespace llvm {
+class MemoryBuffer;
class SMLoc;
class SourceMgr;
} // end namespace llvm
void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind);
private:
+ /// Get a memory buffer for the given file, or the main file of the source
+ /// manager if one doesn't exist.
+ const llvm::MemoryBuffer &getBufferForFile(StringRef filename);
+
/// Convert a location into the given memory buffer into an SMLoc.
llvm::SMLoc convertLocToSMLoc(Location loc);
/// The source manager that we are wrapping.
llvm::SourceMgr &mgr;
+
+ /// Mapping between file name and buffer pointer.
+ llvm::StringMap<const llvm::MemoryBuffer *> filenameToBuf;
};
} // namespace mlir
mgr.PrintMessage(convertLocToSMLoc(loc), getDiagKind(kind), message);
}
-/// Convert a location into the given memory buffer into an SMLoc.
+/// Get a memory buffer for the given file, or nullptr if one is not found.
+const llvm::MemoryBuffer &
+SourceMgrDiagnosticHandler::getBufferForFile(StringRef filename) {
+ // Check for an existing mapping to the buffer id for this file.
+ auto bufferIt = filenameToBuf.find(filename);
+ if (bufferIt != filenameToBuf.end())
+ return *bufferIt->second;
+
+ // Look for a buffer in the manager that has this filename.
+ for (unsigned i = 1, e = mgr.getNumBuffers() + 1; i != e; ++i) {
+ auto *buf = mgr.getMemoryBuffer(i);
+ if (buf->getBufferIdentifier() == filename)
+ return *(filenameToBuf[filename] = buf);
+ }
+
+ return *(filenameToBuf[filename] = mgr.getMemoryBuffer(mgr.getMainFileID()));
+}
+
+/// Get a memory buffer for the given file, or the main file of the source
+/// manager if one doesn't exist. This always returns non-null.
llvm::SMLoc SourceMgrDiagnosticHandler::convertLocToSMLoc(Location loc) {
auto fileLoc = loc.dyn_cast<FileLineColLoc>();
if (!fileLoc)
return llvm::SMLoc();
- auto *membuf = mgr.getMemoryBuffer(mgr.getMainFileID());
+ // Get the buffer for this filename.
+ auto &membuf = getBufferForFile(fileLoc->getFilename());
// TODO: This should really be upstreamed to be a method on llvm::SourceMgr.
// Doing so would allow it to use the offset cache that is already maintained
unsigned columnNo = fileLoc->getColumn();
// Scan for the correct line number.
- const char *position = membuf->getBufferStart();
- const char *end = membuf->getBufferEnd();
+ const char *position = membuf.getBufferStart();
+ const char *end = membuf.getBufferEnd();
// We start counting line and column numbers from 1.
--lineNo;
// If the line/column counter was invalid, return a pointer to the start of
// the buffer.
if (lineNo || position + columnNo > end)
- return llvm::SMLoc::getFromPointer(membuf->getBufferStart());
+ return llvm::SMLoc::getFromPointer(membuf.getBufferStart());
// Otherwise return the right pointer.
return llvm::SMLoc::getFromPointer(position + columnNo);