aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-13 07:05:43 +0000
committerChris Lattner <sabre@nondot.org>2009-03-13 07:05:43 +0000
commitaa739d26b1e65aec7f9afa1cde7e069c081ea355 (patch)
tree47022e6176ab05e1d1efdb65d81a29fff79e07ba /utils
parent49c8aa0d8b2824c70d178c5d55cda64d6613c0d8 (diff)
downloadexternal_llvm-aa739d26b1e65aec7f9afa1cde7e069c081ea355.zip
external_llvm-aa739d26b1e65aec7f9afa1cde7e069c081ea355.tar.gz
external_llvm-aa739d26b1e65aec7f9afa1cde7e069c081ea355.tar.bz2
split buffer management and diagnostic printing out of the tblgen
lexer into its own TGSourceMgr class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/TGLexer.cpp62
-rw-r--r--utils/TableGen/TGLexer.h27
-rw-r--r--utils/TableGen/TGParser.h2
-rw-r--r--utils/TableGen/TGSourceMgr.cpp104
-rw-r--r--utils/TableGen/TGSourceMgr.h88
-rw-r--r--utils/TableGen/TableGen.cpp15
6 files changed, 228 insertions, 70 deletions
diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp
index 0d83e7c..761985e 100644
--- a/utils/TableGen/TGLexer.cpp
+++ b/utils/TableGen/TGLexer.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "TGLexer.h"
+#include "TGSourceMgr.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/MemoryBuffer.h"
#include <ostream>
@@ -23,18 +24,13 @@
#include <cerrno>
using namespace llvm;
-TGLexer::TGLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) {
+TGLexer::TGLexer(TGSourceMgr &SM) : SrcMgr(SM) {
+ CurBuffer = 0;
+ CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
CurPtr = CurBuf->getBufferStart();
TokStart = 0;
}
-TGLexer::~TGLexer() {
- while (!IncludeStack.empty()) {
- delete IncludeStack.back().Buffer;
- IncludeStack.pop_back();
- }
- delete CurBuf;
-}
/// ReturnError - Set the error to the specified string at the specified
/// location. This is defined to always return tgtok::Error.
@@ -43,36 +39,9 @@ tgtok::TokKind TGLexer::ReturnError(const char *Loc, const std::string &Msg) {
return tgtok::Error;
}
-void TGLexer::PrintIncludeStack(std::ostream &OS) const {
- for (unsigned i = 0, e = IncludeStack.size(); i != e; ++i)
- OS << "Included from " << IncludeStack[i].Buffer->getBufferIdentifier()
- << ":" << IncludeStack[i].LineNo << ":\n";
- OS << "Parsing " << CurBuf->getBufferIdentifier() << ":"
- << CurLineNo << ": ";
-}
-/// PrintError - Print the error at the specified location.
-void TGLexer::PrintError(const char *ErrorLoc, const std::string &Msg) const {
- PrintIncludeStack(*cerr.stream());
- cerr << Msg << "\n";
- assert(ErrorLoc && "Location not specified!");
-
- // Scan backward to find the start of the line.
- const char *LineStart = ErrorLoc;
- while (LineStart != CurBuf->getBufferStart() &&
- LineStart[-1] != '\n' && LineStart[-1] != '\r')
- --LineStart;
- // Get the end of the line.
- const char *LineEnd = ErrorLoc;
- while (LineEnd != CurBuf->getBufferEnd() &&
- LineEnd[0] != '\n' && LineEnd[0] != '\r')
- ++LineEnd;
- // Print out the line.
- cerr << std::string(LineStart, LineEnd) << "\n";
- // Print out spaces before the carat.
- for (const char *Pos = LineStart; Pos != ErrorLoc; ++Pos)
- cerr << (*Pos == '\t' ? '\t' : ' ');
- cerr << "^\n";
+void TGLexer::PrintError(LocTy Loc, const std::string &Msg) const {
+ SrcMgr.PrintError(Loc, Msg);
}
int TGLexer::getNextChar() {
@@ -80,7 +49,7 @@ int TGLexer::getNextChar() {
switch (CurChar) {
default:
return (unsigned char)CurChar;
- case 0:
+ case 0: {
// A nul character in the stream is either the end of the current buffer or
// a random nul in the file. Disambiguate that here.
if (CurPtr-1 != CurBuf->getBufferEnd())
@@ -88,18 +57,18 @@ int TGLexer::getNextChar() {
// If this is the end of an included file, pop the parent file off the
// include stack.
- if (!IncludeStack.empty()) {
- delete CurBuf;
- CurBuf = IncludeStack.back().Buffer;
- CurLineNo = IncludeStack.back().LineNo;
- CurPtr = IncludeStack.back().CurPtr;
- IncludeStack.pop_back();
+ TGLocTy ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
+ if (ParentIncludeLoc != TGLocTy()) {
+ CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
+ CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
+ CurPtr = ParentIncludeLoc;
return getNextChar();
}
// Otherwise, return end of file.
--CurPtr; // Another call to lex will return EOF again.
return EOF;
+ }
case '\n':
case '\r':
// Handle the newline character by ignoring it and incrementing the line
@@ -108,8 +77,6 @@ int TGLexer::getNextChar() {
if ((*CurPtr == '\n' || (*CurPtr == '\r')) &&
*CurPtr != CurChar)
++CurPtr; // Eat the two char newline sequence.
-
- ++CurLineNo;
return '\n';
}
}
@@ -272,9 +239,8 @@ bool TGLexer::LexInclude() {
}
// Save the line number and lex buffer of the includer.
- IncludeStack.push_back(IncludeRec(CurBuf, CurPtr, CurLineNo));
+ CurBuffer = SrcMgr.AddNewSourceBuffer(NewBuf, CurPtr);
- CurLineNo = 1; // Reset line numbering.
CurBuf = NewBuf;
CurPtr = CurBuf->getBufferStart();
return false;
diff --git a/utils/TableGen/TGLexer.h b/utils/TableGen/TGLexer.h
index 0e67f68..59e9fa0 100644
--- a/utils/TableGen/TGLexer.h
+++ b/utils/TableGen/TGLexer.h
@@ -22,6 +22,7 @@
namespace llvm {
class MemoryBuffer;
+class TGSourceMgr;
namespace tgtok {
enum TokKind {
@@ -55,33 +56,27 @@ namespace tgtok {
/// TGLexer - TableGen Lexer class.
class TGLexer {
+ TGSourceMgr &SrcMgr;
+
const char *CurPtr;
- unsigned CurLineNo;
- MemoryBuffer *CurBuf;
+ const MemoryBuffer *CurBuf;
// Information about the current token.
const char *TokStart;
tgtok::TokKind CurCode;
std::string CurStrVal; // This is valid for ID, STRVAL, VARNAME, CODEFRAGMENT
int64_t CurIntVal; // This is valid for INTVAL.
-
- /// IncludeRec / IncludeStack - This captures the current set of include
- /// directives we are nested within.
- struct IncludeRec {
- MemoryBuffer *Buffer;
- const char *CurPtr;
- unsigned LineNo;
- IncludeRec(MemoryBuffer *buffer, const char *curPtr, unsigned lineNo)
- : Buffer(buffer), CurPtr(curPtr), LineNo(lineNo) {}
- };
- std::vector<IncludeRec> IncludeStack;
+
+ /// CurBuffer - This is the current buffer index we're lexing from as managed
+ /// by the SourceMgr object.
+ int CurBuffer;
// IncludeDirectories - This is the list of directories we should search for
// include files in.
std::vector<std::string> IncludeDirectories;
public:
- TGLexer(MemoryBuffer *StartBuf);
- ~TGLexer();
+ TGLexer(TGSourceMgr &SrcMgr);
+ ~TGLexer() {}
void setIncludeDirs(const std::vector<std::string> &Dirs) {
IncludeDirectories = Dirs;
@@ -109,8 +104,6 @@ public:
void PrintError(LocTy Loc, const std::string &Msg) const;
- void PrintIncludeStack(std::ostream &OS) const;
-
private:
/// LexToken - Read the next token and return its code.
tgtok::TokKind LexToken();
diff --git a/utils/TableGen/TGParser.h b/utils/TableGen/TGParser.h
index edbc4c1..a1aa8a9 100644
--- a/utils/TableGen/TGParser.h
+++ b/utils/TableGen/TGParser.h
@@ -47,7 +47,7 @@ class TGParser {
public:
typedef TGLexer::LocTy LocTy;
- TGParser(MemoryBuffer *StartBuf) : Lex(StartBuf), CurMultiClass(0) {}
+ TGParser(TGSourceMgr &SrcMgr) : Lex(SrcMgr), CurMultiClass(0) {}
void setIncludeDirs(const std::vector<std::string> &D){Lex.setIncludeDirs(D);}
diff --git a/utils/TableGen/TGSourceMgr.cpp b/utils/TableGen/TGSourceMgr.cpp
new file mode 100644
index 0000000..1e0ab7e
--- /dev/null
+++ b/utils/TableGen/TGSourceMgr.cpp
@@ -0,0 +1,104 @@
+//===- TGSourceMgr.cpp - Manager for Source Buffers & Diagnostics ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the TGSourceMgr class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TGSourceMgr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+TGSourceMgr::~TGSourceMgr() {
+ while (!Buffers.empty()) {
+ delete Buffers.back().Buffer;
+ Buffers.pop_back();
+ }
+}
+
+/// FindBufferContainingLoc - Return the ID of the buffer containing the
+/// specified location, returning -1 if not found.
+int TGSourceMgr::FindBufferContainingLoc(TGLocTy Loc) const {
+ for (unsigned i = 0, e = Buffers.size(); i != e; ++i)
+ if (Loc >= Buffers[i].Buffer->getBufferStart() &&
+ Loc < Buffers[i].Buffer->getBufferEnd())
+ return i;
+ return -1;
+}
+
+/// FindLineNumber - Find the line number for the specified location in the
+/// specified file. This is not a fast method.
+unsigned TGSourceMgr::FindLineNumber(TGLocTy Loc, int BufferID) const {
+ if (BufferID == -1) BufferID = FindBufferContainingLoc(Loc);
+ assert(BufferID != -1 && "Invalid Location!");
+
+ MemoryBuffer *Buff = getBufferInfo(BufferID).Buffer;
+
+ // Count the number of \n's between the start of the file and the specified
+ // location.
+ unsigned LineNo = 1;
+
+ const char *Ptr = Buff->getBufferStart();
+
+ for (; Ptr != Loc; ++Ptr)
+ if (*Ptr == '\n') ++LineNo;
+ return LineNo;
+}
+
+void TGSourceMgr::PrintIncludeStack(TGLocTy IncludeLoc) const {
+ if (IncludeLoc == TGLocTy()) return; // Top of stack.
+
+ int CurBuf = FindBufferContainingLoc(IncludeLoc);
+ assert(CurBuf != -1 && "Invalid or unspecified location!");
+
+ PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc);
+
+ errs() << "Included from "
+ << getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
+ << ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
+}
+
+
+void TGSourceMgr::PrintError(TGLocTy ErrorLoc, const std::string &Msg) const {
+ raw_ostream &OS = errs();
+
+ // First thing to do: find the current buffer containing the specified
+ // location.
+ int CurBuf = FindBufferContainingLoc(ErrorLoc);
+ assert(CurBuf != -1 && "Invalid or unspecified location!");
+
+ PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc);
+
+ MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer;
+
+
+ OS << "Parsing " << CurMB->getBufferIdentifier() << ":"
+ << FindLineNumber(ErrorLoc, CurBuf) << ": ";
+
+ OS << Msg << "\n";
+ assert(ErrorLoc && "Location not specified!");
+
+ // Scan backward to find the start of the line.
+ const char *LineStart = ErrorLoc;
+ while (LineStart != CurMB->getBufferStart() &&
+ LineStart[-1] != '\n' && LineStart[-1] != '\r')
+ --LineStart;
+ // Get the end of the line.
+ const char *LineEnd = ErrorLoc;
+ while (LineEnd != CurMB->getBufferEnd() &&
+ LineEnd[0] != '\n' && LineEnd[0] != '\r')
+ ++LineEnd;
+ // Print out the line.
+ OS << std::string(LineStart, LineEnd) << "\n";
+ // Print out spaces before the carat.
+ for (const char *Pos = LineStart; Pos != ErrorLoc; ++Pos)
+ OS << (*Pos == '\t' ? '\t' : ' ');
+ OS << "^\n";
+}
diff --git a/utils/TableGen/TGSourceMgr.h b/utils/TableGen/TGSourceMgr.h
new file mode 100644
index 0000000..9a61a9b
--- /dev/null
+++ b/utils/TableGen/TGSourceMgr.h
@@ -0,0 +1,88 @@
+//===- TGSourceMgr.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 TGSourceMgr class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TGSOURCEMGR_H
+#define TGSOURCEMGR_H
+
+#include <vector>
+
+namespace llvm {
+ class MemoryBuffer;
+
+/// FIXME: Make this a struct that is opaque.
+typedef const char *TGLocTy;
+
+/// TGSourceMgr - This owns the files read by tblgen, handles include stacks,
+/// and handles printing of diagnostics.
+class TGSourceMgr {
+ struct SrcBuffer {
+ /// Buffer - The memory buffer for the file.
+ MemoryBuffer *Buffer;
+
+ /// IncludeLoc - This is the location of the parent include, or null if at
+ /// the top level.
+ TGLocTy IncludeLoc;
+ };
+
+ /// Buffers - This is all of the buffers that we are reading from.
+ std::vector<SrcBuffer> Buffers;
+
+ TGSourceMgr(const TGSourceMgr&); // DO NOT IMPLEMENT
+ void operator=(const TGSourceMgr&); // DO NOT IMPLEMENT
+public:
+ TGSourceMgr() {}
+ ~TGSourceMgr();
+
+ const SrcBuffer &getBufferInfo(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i];
+ }
+
+ const MemoryBuffer *getMemoryBuffer(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i].Buffer;
+ }
+
+ TGLocTy getParentIncludeLoc(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i].IncludeLoc;
+ }
+
+ unsigned AddNewSourceBuffer(MemoryBuffer *F, TGLocTy IncludeLoc) {
+ SrcBuffer NB;
+ NB.Buffer = F;
+ NB.IncludeLoc = IncludeLoc;
+ Buffers.push_back(NB);
+ return Buffers.size()-1;
+ }
+
+ /// FindBufferContainingLoc - Return the ID of the buffer containing the
+ /// specified location, returning -1 if not found.
+ int FindBufferContainingLoc(TGLocTy Loc) const;
+
+ /// FindLineNumber - Find the line number for the specified location in the
+ /// specified file. This is not a fast method.
+ unsigned FindLineNumber(TGLocTy Loc, int BufferID = -1) const;
+
+
+ /// PrintError - Emit an error message about the specified location with the
+ /// specified string.
+ void PrintError(TGLocTy ErrorLoc, const std::string &Msg) const;
+
+private:
+ void PrintIncludeStack(TGLocTy IncludeLoc) const;
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 147db12..c6a1f2e 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -17,6 +17,7 @@
#include "Record.h"
#include "TGParser.h"
+#include "TGSourceMgr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Signals.h"
@@ -113,15 +114,19 @@ RecordKeeper llvm::Records;
/// ParseFile - this function begins the parsing of the specified tablegen
/// file.
static bool ParseFile(const std::string &Filename,
- const std::vector<std::string> &IncludeDirs) {
+ const std::vector<std::string> &IncludeDirs,
+ TGSourceMgr &SrcMgr) {
std::string ErrorStr;
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr);
if (F == 0) {
cerr << "Could not open input file '" + Filename + "': " << ErrorStr <<"\n";
return true;
}
-
- TGParser Parser(F);
+
+ // Tell SrcMgr about this buffer, which is what TGParser will pick up.
+ SrcMgr.AddNewSourceBuffer(F, TGLocTy());
+
+ TGParser Parser(SrcMgr);
// Record the location of the include directory so that the lexer can find
// it later.
@@ -135,8 +140,10 @@ int main(int argc, char **argv) {
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
+ TGSourceMgr SrcMgr;
+
// Parse the input file.
- if (ParseFile(InputFilename, IncludeDirs))
+ if (ParseFile(InputFilename, IncludeDirs, SrcMgr))
return 1;
std::ostream *Out = cout.stream();