예제 #1
0
/// 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);
}
예제 #2
0
/// 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);
}