| 236 | } |
| 237 | |
| 238 | SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, |
| 239 | const Twine &Msg, ArrayRef<SMRange> Ranges, |
| 240 | ArrayRef<SMFixIt> FixIts) const { |
| 241 | // First thing to do: find the current buffer containing the specified |
| 242 | // location to pull out the source line. |
| 243 | SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges; |
| 244 | std::pair<unsigned, unsigned> LineAndCol; |
| 245 | StringRef BufferID = "<unknown>"; |
| 246 | std::string LineStr; |
| 247 | |
| 248 | if (Loc.isValid()) { |
| 249 | unsigned CurBuf = FindBufferContainingLoc(Loc); |
| 250 | assert(CurBuf && "Invalid or unspecified location!"); |
| 251 | |
| 252 | const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf); |
| 253 | BufferID = CurMB->getBufferIdentifier(); |
| 254 | |
| 255 | // Scan backward to find the start of the line. |
| 256 | const char *LineStart = Loc.getPointer(); |
| 257 | const char *BufStart = CurMB->getBufferStart(); |
| 258 | while (LineStart != BufStart && LineStart[-1] != '\n' && |
| 259 | LineStart[-1] != '\r') |
| 260 | --LineStart; |
| 261 | |
| 262 | // Get the end of the line. |
| 263 | const char *LineEnd = Loc.getPointer(); |
| 264 | const char *BufEnd = CurMB->getBufferEnd(); |
| 265 | while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r') |
| 266 | ++LineEnd; |
| 267 | LineStr = std::string(LineStart, LineEnd); |
| 268 | |
| 269 | // Convert any ranges to column ranges that only intersect the line of the |
| 270 | // location. |
| 271 | for (unsigned i = 0, e = Ranges.size(); i != e; ++i) { |
| 272 | SMRange R = Ranges[i]; |
| 273 | if (!R.isValid()) |
| 274 | continue; |
| 275 | |
| 276 | // If the line doesn't contain any part of the range, then ignore it. |
| 277 | if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart) |
| 278 | continue; |
| 279 | |
| 280 | // Ignore pieces of the range that go onto other lines. |
| 281 | if (R.Start.getPointer() < LineStart) |
| 282 | R.Start = SMLoc::getFromPointer(LineStart); |
| 283 | if (R.End.getPointer() > LineEnd) |
| 284 | R.End = SMLoc::getFromPointer(LineEnd); |
| 285 | |
| 286 | // Translate from SMLoc ranges to column ranges. |
| 287 | // FIXME: Handle multibyte characters. |
| 288 | ColRanges.push_back(std::make_pair(R.Start.getPointer() - LineStart, |
| 289 | R.End.getPointer() - LineStart)); |
| 290 | } |
| 291 | |
| 292 | LineAndCol = getLineAndColumn(Loc, CurBuf); |
| 293 | } |
| 294 | |
| 295 | return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first, |
nothing calls this directly
no test coverage detected