1 //===- TGSourceMgr.cpp - Manager for Source Buffers & Diagnostics ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the TGSourceMgr class.
12 //===----------------------------------------------------------------------===//
14 #include "TGSourceMgr.h"
15 #include "llvm/Support/MemoryBuffer.h"
16 #include "llvm/Support/raw_ostream.h"
19 TGSourceMgr::~TGSourceMgr() {
20 while (!Buffers
.empty()) {
21 delete Buffers
.back().Buffer
;
26 /// FindBufferContainingLoc - Return the ID of the buffer containing the
27 /// specified location, returning -1 if not found.
28 int TGSourceMgr::FindBufferContainingLoc(TGLoc Loc
) const {
29 for (unsigned i
= 0, e
= Buffers
.size(); i
!= e
; ++i
)
30 if (Loc
.getPointer() >= Buffers
[i
].Buffer
->getBufferStart() &&
31 // Use <= here so that a pointer to the null at the end of the buffer
32 // is included as part of the buffer.
33 Loc
.getPointer() <= Buffers
[i
].Buffer
->getBufferEnd())
38 /// FindLineNumber - Find the line number for the specified location in the
39 /// specified file. This is not a fast method.
40 unsigned TGSourceMgr::FindLineNumber(TGLoc Loc
, int BufferID
) const {
41 if (BufferID
== -1) BufferID
= FindBufferContainingLoc(Loc
);
42 assert(BufferID
!= -1 && "Invalid Location!");
44 MemoryBuffer
*Buff
= getBufferInfo(BufferID
).Buffer
;
46 // Count the number of \n's between the start of the file and the specified
50 const char *Ptr
= Buff
->getBufferStart();
52 for (; TGLoc::getFromPointer(Ptr
) != Loc
; ++Ptr
)
53 if (*Ptr
== '\n') ++LineNo
;
57 void TGSourceMgr::PrintIncludeStack(TGLoc IncludeLoc
) const {
58 if (IncludeLoc
== TGLoc()) return; // Top of stack.
60 int CurBuf
= FindBufferContainingLoc(IncludeLoc
);
61 assert(CurBuf
!= -1 && "Invalid or unspecified location!");
63 PrintIncludeStack(getBufferInfo(CurBuf
).IncludeLoc
);
65 errs() << "Included from "
66 << getBufferInfo(CurBuf
).Buffer
->getBufferIdentifier()
67 << ":" << FindLineNumber(IncludeLoc
, CurBuf
) << ":\n";
71 void TGSourceMgr::PrintError(TGLoc ErrorLoc
, const std::string
&Msg
) const {
72 raw_ostream
&OS
= errs();
74 // First thing to do: find the current buffer containing the specified
76 int CurBuf
= FindBufferContainingLoc(ErrorLoc
);
77 assert(CurBuf
!= -1 && "Invalid or unspecified location!");
79 PrintIncludeStack(getBufferInfo(CurBuf
).IncludeLoc
);
81 MemoryBuffer
*CurMB
= getBufferInfo(CurBuf
).Buffer
;
84 OS
<< "Parsing " << CurMB
->getBufferIdentifier() << ":"
85 << FindLineNumber(ErrorLoc
, CurBuf
) << ": ";
89 // Scan backward to find the start of the line.
90 const char *LineStart
= ErrorLoc
.getPointer();
91 while (LineStart
!= CurMB
->getBufferStart() &&
92 LineStart
[-1] != '\n' && LineStart
[-1] != '\r')
94 // Get the end of the line.
95 const char *LineEnd
= ErrorLoc
.getPointer();
96 while (LineEnd
!= CurMB
->getBufferEnd() &&
97 LineEnd
[0] != '\n' && LineEnd
[0] != '\r')
99 // Print out the line.
100 OS
<< std::string(LineStart
, LineEnd
) << "\n";
101 // Print out spaces before the caret.
102 for (const char *Pos
= LineStart
; Pos
!= ErrorLoc
.getPointer(); ++Pos
)
103 OS
<< (*Pos
== '\t' ? '\t' : ' ');