Mercurial > hg > CbC > CbC_llvm
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 { |