[llvm-commits] [llvm] r66873 - in /llvm/trunk/utils/TableGen: TGLexer.cpp TGLexer.h TGParser.h TGSourceMgr.cpp TGSourceMgr.h TableGen.cpp

Chris Lattner sabre at nondot.org
Fri Mar 13 00:05:44 PDT 2009


Author: lattner
Date: Fri Mar 13 02:05:43 2009
New Revision: 66873

URL: http://llvm.org/viewvc/llvm-project?rev=66873&view=rev
Log:
split buffer management and diagnostic printing out of the tblgen
lexer into its own TGSourceMgr class.

Added:
    llvm/trunk/utils/TableGen/TGSourceMgr.cpp
    llvm/trunk/utils/TableGen/TGSourceMgr.h
Modified:
    llvm/trunk/utils/TableGen/TGLexer.cpp
    llvm/trunk/utils/TableGen/TGLexer.h
    llvm/trunk/utils/TableGen/TGParser.h
    llvm/trunk/utils/TableGen/TableGen.cpp

Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=66873&r1=66872&r2=66873&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/utils/TableGen/TGLexer.cpp Fri Mar 13 02:05:43 2009
@@ -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 @@
   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 @@
   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 @@
     
     // 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 @@
     if ((*CurPtr == '\n' || (*CurPtr == '\r')) &&
         *CurPtr != CurChar)
       ++CurPtr;  // Eat the two char newline sequence.
-      
-    ++CurLineNo;
     return '\n';
   }  
 }
@@ -272,9 +239,8 @@
   }
   
   // 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;

Modified: llvm/trunk/utils/TableGen/TGLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=66873&r1=66872&r2=66873&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.h (original)
+++ llvm/trunk/utils/TableGen/TGLexer.h Fri Mar 13 02:05:43 2009
@@ -22,6 +22,7 @@
 
 namespace llvm {
 class MemoryBuffer;
+class TGSourceMgr;
   
 namespace tgtok {
   enum TokKind {
@@ -55,33 +56,27 @@
 
 /// 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 @@
 
   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();

Modified: llvm/trunk/utils/TableGen/TGParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.h?rev=66873&r1=66872&r2=66873&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.h (original)
+++ llvm/trunk/utils/TableGen/TGParser.h Fri Mar 13 02:05:43 2009
@@ -47,7 +47,7 @@
 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);}
 

Added: llvm/trunk/utils/TableGen/TGSourceMgr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGSourceMgr.cpp?rev=66873&view=auto

==============================================================================
--- llvm/trunk/utils/TableGen/TGSourceMgr.cpp (added)
+++ llvm/trunk/utils/TableGen/TGSourceMgr.cpp Fri Mar 13 02:05:43 2009
@@ -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";
+}

Added: llvm/trunk/utils/TableGen/TGSourceMgr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGSourceMgr.h?rev=66873&view=auto

==============================================================================
--- llvm/trunk/utils/TableGen/TGSourceMgr.h (added)
+++ llvm/trunk/utils/TableGen/TGSourceMgr.h Fri Mar 13 02:05:43 2009
@@ -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

Modified: llvm/trunk/utils/TableGen/TableGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=66873&r1=66872&r2=66873&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TableGen.cpp (original)
+++ llvm/trunk/utils/TableGen/TableGen.cpp Fri Mar 13 02:05:43 2009
@@ -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 @@
 /// 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 @@
   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();





More information about the llvm-commits mailing list