add an explicit class for holding llvm::SourceMgr diagnostics and use

it to print them.  This gives us column numbers in the diag line.  Before:

t.s:4: error: unexpected token in argument list
 mov %eax %edx
          ^

now:
t.s:4:11: error: unexpected token in argument list
 mov %eax %edx
          ^



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74732 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2009-07-02 22:24:20 +00:00
parent b50ea5c48f
commit 2f510aed9c
2 changed files with 88 additions and 25 deletions

View File

@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
//
// This file declares the SourceMgr class. This class is used as a simple
// substrate for diagnostics, #include handling, and other low level things for
// simple parsers.
// This file declares the SMLoc, SMDiagnostic and SourceMgr classes. This
// provides a simple substrate for diagnostics, #include handling, and other low
// level things for simple parsers.
//
//===----------------------------------------------------------------------===//
@ -23,6 +23,8 @@
namespace llvm {
class MemoryBuffer;
class SourceMgr;
class SMDiagnostic;
class raw_ostream;
class SMLoc {
const char *Ptr;
@ -44,8 +46,8 @@ public:
}
};
/// SourceMgr - This owns the files read by tblgen, handles include stacks,
/// and handles printing of diagnostics.
/// SourceMgr - This owns the files read by a parser, handles include stacks,
/// and handles diagnostic wrangling.
class SourceMgr {
struct SrcBuffer {
/// Buffer - The memory buffer for the file.
@ -117,7 +119,35 @@ public:
void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
private:
void PrintIncludeStack(SMLoc IncludeLoc) const;
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
};
/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
/// allowing printing to a raw_ostream as a caret diagnostic.
class SMDiagnostic {
std::string Filename;
int LineNo, ColumnNo;
std::string Message, LineContents;
public:
SMDiagnostic() : LineNo(0), ColumnNo(0) {}
SMDiagnostic(const std::string &FN, int Line, int Col,
const std::string &Msg, const std::string &LineStr)
: Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
LineContents(LineStr) {}
SMDiagnostic(const SMDiagnostic &RHS) {
operator=(RHS);
}
void operator=(const SMDiagnostic &E) {
Filename = E.Filename;
LineNo = E.LineNo;
ColumnNo = E.ColumnNo;
Message = E.Message;
LineContents = E.LineContents;
}
void Print(const char *ProgName, raw_ostream &S);
};
} // end llvm namespace

View File

@ -76,17 +76,17 @@ unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const {
return LineNo;
}
void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc) const {
void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
if (IncludeLoc == SMLoc()) return; // Top of stack.
int CurBuf = FindBufferContainingLoc(IncludeLoc);
assert(CurBuf != -1 && "Invalid or unspecified location!");
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc);
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
errs() << "Included from "
<< getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
<< ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
OS << "Included from "
<< getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
<< ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
}
@ -99,19 +99,11 @@ void SourceMgr::PrintMessage(SMLoc Loc, const std::string &Msg,
int CurBuf = FindBufferContainingLoc(Loc);
assert(CurBuf != -1 && "Invalid or unspecified location!");
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc);
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer;
OS << CurMB->getBufferIdentifier() << ":"
<< FindLineNumber(Loc, CurBuf) << ": ";
if (Type)
OS << Type << ": ";
OS << Msg << "\n";
// Scan backward to find the start of the line.
const char *LineStart = Loc.getPointer();
while (LineStart != CurMB->getBufferStart() &&
@ -122,10 +114,51 @@ void SourceMgr::PrintMessage(SMLoc Loc, const std::string &Msg,
while (LineEnd != CurMB->getBufferEnd() &&
LineEnd[0] != '\n' && LineEnd[0] != '\r')
++LineEnd;
std::string PrintedMsg;
if (Type) {
PrintedMsg = Type;
PrintedMsg += ": ";
}
PrintedMsg += Msg;
// Print out the line.
OS << std::string(LineStart, LineEnd) << "\n";
// Print out spaces before the caret.
for (const char *Pos = LineStart; Pos != Loc.getPointer(); ++Pos)
OS << (*Pos == '\t' ? '\t' : ' ');
OS << "^\n";
SMDiagnostic(CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf),
Loc.getPointer()-LineStart, PrintedMsg,
std::string(LineStart, LineEnd)).Print(0, OS);
}
//===----------------------------------------------------------------------===//
// SMDiagnostic Implementation
//===----------------------------------------------------------------------===//
void SMDiagnostic::Print(const char *ProgName, raw_ostream &S) {
if (ProgName && ProgName[0])
S << ProgName << ": ";
if (Filename == "-")
S << "<stdin>";
else
S << Filename;
if (LineNo != -1) {
S << ':' << LineNo;
if (ColumnNo != -1)
S << ':' << (ColumnNo+1);
}
S << ": " << Message << '\n';
if (LineNo != -1 && ColumnNo != -1) {
S << LineContents << '\n';
// Print out spaces/tabs before the caret.
for (unsigned i = 0; i != unsigned(ColumnNo); ++i)
S << (LineContents[i] == '\t' ? '\t' : ' ');
S << "^\n";
}
}