/// GetMessage - Return an SMDiagnostic at the specified location with the /// specified string. /// /// @param Type - If non-null, the kind of message (e.g., "error") which is /// prefixed to the message. SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges) const { // First thing to do: find the current buffer containing the specified // location. int CurBuf = FindBufferContainingLoc(Loc); assert(CurBuf != -1 && "Invalid or unspecified location!"); MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer; // Scan backward to find the start of the line. const char *LineStart = Loc.getPointer(); while (LineStart != CurMB->getBufferStart() && LineStart[-1] != '\n' && LineStart[-1] != '\r') --LineStart; // Get the end of the line. const char *LineEnd = Loc.getPointer(); while (LineEnd != CurMB->getBufferEnd() && LineEnd[0] != '\n' && LineEnd[0] != '\r') ++LineEnd; std::string LineStr(LineStart, LineEnd); // Convert any ranges to column ranges that only intersect the line of the // location. SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges; for (unsigned i = 0, e = Ranges.size(); i != e; ++i) { SMRange R = Ranges[i]; if (!R.isValid()) continue; // If the line doesn't contain any part of the range, then ignore it. if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart) continue; // Ignore pieces of the range that go onto other lines. if (R.Start.getPointer() < LineStart) R.Start = SMLoc::getFromPointer(LineStart); if (R.End.getPointer() > LineEnd) R.End = SMLoc::getFromPointer(LineEnd); // Translate from SMLoc ranges to column ranges. ColRanges.push_back(std::make_pair(R.Start.getPointer()-LineStart, R.End.getPointer()-LineStart)); } return SMDiagnostic(*this, Loc, CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf), Loc.getPointer()-LineStart, Kind, Msg.str(), LineStr, ColRanges); }
/// GetMessage - Return an SMDiagnostic at the specified location with the /// specified string. /// /// @param Type - If non-null, the kind of message (e.g., "error") which is /// prefixed to the message. SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, const Twine &Msg, const char *Type, bool ShowLine) const { // First thing to do: find the current buffer containing the specified // location. int CurBuf = FindBufferContainingLoc(Loc); assert(CurBuf != -1 && "Invalid or unspecified location!"); MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer; // Scan backward to find the start of the line. const char *LineStart = Loc.getPointer(); while (LineStart != CurMB->getBufferStart() && LineStart[-1] != '\n' && LineStart[-1] != '\r') --LineStart; std::string LineStr; if (ShowLine) { // Get the end of the line. const char *LineEnd = Loc.getPointer(); while (LineEnd != CurMB->getBufferEnd() && LineEnd[0] != '\n' && LineEnd[0] != '\r') ++LineEnd; LineStr = std::string(LineStart, LineEnd); } std::string PrintedMsg; raw_string_ostream OS(PrintedMsg); if (Type) OS << Type << ": "; OS << Msg; return SMDiagnostic(*this, Loc, CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf), Loc.getPointer()-LineStart, OS.str(), LineStr, ShowLine); }