comparison lib/Support/SourceMgr.cpp @ 77:54457678186b LLVM3.6

LLVM 3.6
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Mon, 08 Sep 2014 22:06:00 +0900
parents 95c75e76d11b
children 60c9769439b8
comparison
equal deleted inserted replaced
34:e874dbf0ad9d 77:54457678186b
12 // simple parsers. 12 // simple parsers.
13 // 13 //
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "llvm/Support/SourceMgr.h" 16 #include "llvm/Support/SourceMgr.h"
17 #include "llvm/ADT/OwningPtr.h"
18 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/Twine.h" 18 #include "llvm/ADT/Twine.h"
20 #include "llvm/Support/Locale.h" 19 #include "llvm/Support/Locale.h"
21 #include "llvm/Support/MemoryBuffer.h" 20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/Path.h"
22 #include "llvm/Support/raw_ostream.h" 22 #include "llvm/Support/raw_ostream.h"
23 #include "llvm/Support/system_error.h" 23 #include <system_error>
24 using namespace llvm; 24 using namespace llvm;
25 25
26 static const size_t TabStop = 8; 26 static const size_t TabStop = 8;
27 27
28 namespace { 28 namespace {
29 struct LineNoCacheTy { 29 struct LineNoCacheTy {
30 int LastQueryBufferID; 30 unsigned LastQueryBufferID;
31 const char *LastQuery; 31 const char *LastQuery;
32 unsigned LineNoOfQuery; 32 unsigned LineNoOfQuery;
33 }; 33 };
34 } 34 }
35 35
40 40
41 SourceMgr::~SourceMgr() { 41 SourceMgr::~SourceMgr() {
42 // Delete the line # cache if allocated. 42 // Delete the line # cache if allocated.
43 if (LineNoCacheTy *Cache = getCache(LineNoCache)) 43 if (LineNoCacheTy *Cache = getCache(LineNoCache))
44 delete Cache; 44 delete Cache;
45 45 }
46 while (!Buffers.empty()) { 46
47 delete Buffers.back().Buffer; 47 unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
48 Buffers.pop_back(); 48 SMLoc IncludeLoc,
49 } 49 std::string &IncludedFile) {
50 }
51
52 /// AddIncludeFile - Search for a file with the specified name in the current
53 /// directory or in one of the IncludeDirs. If no file is found, this returns
54 /// ~0, otherwise it returns the buffer ID of the stacked file.
55 size_t SourceMgr::AddIncludeFile(const std::string &Filename,
56 SMLoc IncludeLoc,
57 std::string &IncludedFile) {
58 OwningPtr<MemoryBuffer> NewBuf;
59 IncludedFile = Filename; 50 IncludedFile = Filename;
60 MemoryBuffer::getFile(IncludedFile.c_str(), NewBuf); 51 ErrorOr<std::unique_ptr<MemoryBuffer>> NewBufOrErr =
52 MemoryBuffer::getFile(IncludedFile.c_str());
61 53
62 // If the file didn't exist directly, see if it's in an include path. 54 // If the file didn't exist directly, see if it's in an include path.
63 for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) { 55 for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
64 IncludedFile = IncludeDirectories[i] + "/" + Filename; 56 ++i) {
65 MemoryBuffer::getFile(IncludedFile.c_str(), NewBuf); 57 IncludedFile =
66 } 58 IncludeDirectories[i] + sys::path::get_separator().data() + Filename;
67 59 NewBufOrErr = MemoryBuffer::getFile(IncludedFile.c_str());
68 if (!NewBuf) return ~0U; 60 }
69 61
70 return AddNewSourceBuffer(NewBuf.take(), IncludeLoc); 62 if (!NewBufOrErr)
71 } 63 return 0;
72 64
73 65 return AddNewSourceBuffer(std::move(*NewBufOrErr), IncludeLoc);
74 /// FindBufferContainingLoc - Return the ID of the buffer containing the 66 }
75 /// specified location, returning -1 if not found. 67
76 int SourceMgr::FindBufferContainingLoc(SMLoc Loc) const { 68 unsigned SourceMgr::FindBufferContainingLoc(SMLoc Loc) const {
77 for (unsigned i = 0, e = Buffers.size(); i != e; ++i) 69 for (unsigned i = 0, e = Buffers.size(); i != e; ++i)
78 if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() && 70 if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
79 // Use <= here so that a pointer to the null at the end of the buffer 71 // Use <= here so that a pointer to the null at the end of the buffer
80 // is included as part of the buffer. 72 // is included as part of the buffer.
81 Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd()) 73 Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
82 return i; 74 return i + 1;
83 return -1; 75 return 0;
84 } 76 }
85 77
86 /// getLineAndColumn - Find the line and column number for the specified
87 /// location in the specified file. This is not a fast method.
88 std::pair<unsigned, unsigned> 78 std::pair<unsigned, unsigned>
89 SourceMgr::getLineAndColumn(SMLoc Loc, int BufferID) const { 79 SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
90 if (BufferID == -1) BufferID = FindBufferContainingLoc(Loc); 80 if (!BufferID)
91 assert(BufferID != -1 && "Invalid Location!"); 81 BufferID = FindBufferContainingLoc(Loc);
92 82 assert(BufferID && "Invalid Location!");
93 MemoryBuffer *Buff = getBufferInfo(BufferID).Buffer; 83
84 const MemoryBuffer *Buff = getMemoryBuffer(BufferID);
94 85
95 // Count the number of \n's between the start of the file and the specified 86 // Count the number of \n's between the start of the file and the specified
96 // location. 87 // location.
97 unsigned LineNo = 1; 88 unsigned LineNo = 1;
98 89
113 // we see. 104 // we see.
114 for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr) 105 for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr)
115 if (*Ptr == '\n') ++LineNo; 106 if (*Ptr == '\n') ++LineNo;
116 107
117 // Allocate the line number cache if it doesn't exist. 108 // Allocate the line number cache if it doesn't exist.
118 if (LineNoCache == 0) 109 if (!LineNoCache)
119 LineNoCache = new LineNoCacheTy(); 110 LineNoCache = new LineNoCacheTy();
120 111
121 // Update the line # cache. 112 // Update the line # cache.
122 LineNoCacheTy &Cache = *getCache(LineNoCache); 113 LineNoCacheTy &Cache = *getCache(LineNoCache);
123 Cache.LastQueryBufferID = BufferID; 114 Cache.LastQueryBufferID = BufferID;
130 } 121 }
131 122
132 void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const { 123 void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
133 if (IncludeLoc == SMLoc()) return; // Top of stack. 124 if (IncludeLoc == SMLoc()) return; // Top of stack.
134 125
135 int CurBuf = FindBufferContainingLoc(IncludeLoc); 126 unsigned CurBuf = FindBufferContainingLoc(IncludeLoc);
136 assert(CurBuf != -1 && "Invalid or unspecified location!"); 127 assert(CurBuf && "Invalid or unspecified location!");
137 128
138 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS); 129 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
139 130
140 OS << "Included from " 131 OS << "Included from "
141 << getBufferInfo(CurBuf).Buffer->getBufferIdentifier() 132 << getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
142 << ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n"; 133 << ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
143 } 134 }
144 135
145 136
146 /// GetMessage - Return an SMDiagnostic at the specified location with the
147 /// specified string.
148 ///
149 /// @param Type - If non-null, the kind of message (e.g., "error") which is
150 /// prefixed to the message.
151 SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, 137 SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
152 const Twine &Msg, 138 const Twine &Msg,
153 ArrayRef<SMRange> Ranges, 139 ArrayRef<SMRange> Ranges,
154 ArrayRef<SMFixIt> FixIts) const { 140 ArrayRef<SMFixIt> FixIts) const {
155 141
159 std::pair<unsigned, unsigned> LineAndCol; 145 std::pair<unsigned, unsigned> LineAndCol;
160 const char *BufferID = "<unknown>"; 146 const char *BufferID = "<unknown>";
161 std::string LineStr; 147 std::string LineStr;
162 148
163 if (Loc.isValid()) { 149 if (Loc.isValid()) {
164 int CurBuf = FindBufferContainingLoc(Loc); 150 unsigned CurBuf = FindBufferContainingLoc(Loc);
165 assert(CurBuf != -1 && "Invalid or unspecified location!"); 151 assert(CurBuf && "Invalid or unspecified location!");
166 152
167 MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer; 153 const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf);
168 BufferID = CurMB->getBufferIdentifier(); 154 BufferID = CurMB->getBufferIdentifier();
169 155
170 // Scan backward to find the start of the line. 156 // Scan backward to find the start of the line.
171 const char *LineStart = Loc.getPointer(); 157 const char *LineStart = Loc.getPointer();
172 const char *BufStart = CurMB->getBufferStart(); 158 const char *BufStart = CurMB->getBufferStart();
209 return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first, 195 return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
210 LineAndCol.second-1, Kind, Msg.str(), 196 LineAndCol.second-1, Kind, Msg.str(),
211 LineStr, ColRanges, FixIts); 197 LineStr, ColRanges, FixIts);
212 } 198 }
213 199
200 void SourceMgr::PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
201 bool ShowColors) const {
202 // Report the message with the diagnostic handler if present.
203 if (DiagHandler) {
204 DiagHandler(Diagnostic, DiagContext);
205 return;
206 }
207
208 if (Diagnostic.getLoc().isValid()) {
209 unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc());
210 assert(CurBuf && "Invalid or unspecified location!");
211 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
212 }
213
214 Diagnostic.print(nullptr, OS, ShowColors);
215 }
216
214 void SourceMgr::PrintMessage(raw_ostream &OS, SMLoc Loc, 217 void SourceMgr::PrintMessage(raw_ostream &OS, SMLoc Loc,
215 SourceMgr::DiagKind Kind, 218 SourceMgr::DiagKind Kind,
216 const Twine &Msg, ArrayRef<SMRange> Ranges, 219 const Twine &Msg, ArrayRef<SMRange> Ranges,
217 ArrayRef<SMFixIt> FixIts, bool ShowColors) const { 220 ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
218 SMDiagnostic Diagnostic = GetMessage(Loc, Kind, Msg, Ranges, FixIts); 221 PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors);
219
220 // Report the message with the diagnostic handler if present.
221 if (DiagHandler) {
222 DiagHandler(Diagnostic, DiagContext);
223 return;
224 }
225
226 if (Loc != SMLoc()) {
227 int CurBuf = FindBufferContainingLoc(Loc);
228 assert(CurBuf != -1 && "Invalid or unspecified location!");
229 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
230 }
231
232 Diagnostic.print(0, OS, ShowColors);
233 } 222 }
234 223
235 void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, 224 void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
236 const Twine &Msg, ArrayRef<SMRange> Ranges, 225 const Twine &Msg, ArrayRef<SMRange> Ranges,
237 ArrayRef<SMFixIt> FixIts, bool ShowColors) const { 226 ArrayRef<SMFixIt> FixIts, bool ShowColors) const {