diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 19:34:23 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 19:34:23 +0000 | 
| commit | 58b69754af0cbff56b1cfce9be9392e4451f6628 (patch) | |
| tree | eacfc83d988e4b9d11114387ae7dc41243f2a363 /lib/Support/SourceMgr.cpp | |
| parent | 0378662f5bd3dbe8305a485b0282bceb8b52f465 (diff) | |
Notes
Diffstat (limited to 'lib/Support/SourceMgr.cpp')
| -rw-r--r-- | lib/Support/SourceMgr.cpp | 121 | 
1 files changed, 67 insertions, 54 deletions
| diff --git a/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp index 15278c598e52c..e4e01be038029 100644 --- a/lib/Support/SourceMgr.cpp +++ b/lib/Support/SourceMgr.cpp @@ -79,9 +79,10 @@ int SourceMgr::FindBufferContainingLoc(SMLoc Loc) const {    return -1;  } -/// FindLineNumber - Find the line number for the specified location in the -/// specified file.  This is not a fast method. -unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const { +/// getLineAndColumn - Find the line and column number for the specified +/// location in the specified file.  This is not a fast method. +std::pair<unsigned, unsigned> +SourceMgr::getLineAndColumn(SMLoc Loc, int BufferID) const {    if (BufferID == -1) BufferID = FindBufferContainingLoc(Loc);    assert(BufferID != -1 && "Invalid Location!"); @@ -91,7 +92,8 @@ unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const {    // location.    unsigned LineNo = 1; -  const char *Ptr = Buff->getBufferStart(); +  const char *BufStart = Buff->getBufferStart(); +  const char *Ptr = BufStart;    // If we have a line number cache, and if the query is to a later point in the    // same file, start searching from the last query location.  This optimizes @@ -108,7 +110,6 @@ unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const {    for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr)      if (*Ptr == '\n') ++LineNo; -    // Allocate the line number cache if it doesn't exist.    if (LineNoCache == 0)      LineNoCache = new LineNoCacheTy(); @@ -118,7 +119,10 @@ unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const {    Cache.LastQueryBufferID = BufferID;    Cache.LastQuery = Ptr;    Cache.LineNoOfQuery = LineNo; -  return LineNo; +   +  size_t NewlineOffs = StringRef(BufStart, Ptr-BufStart).find_last_of("\n\r"); +  if (NewlineOffs == StringRef::npos) NewlineOffs = ~(size_t)0; +  return std::make_pair(LineNo, Ptr-BufStart-NewlineOffs);  }  void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const { @@ -145,50 +149,59 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,                                     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. +  // location to pull out the source line.    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); +  std::pair<unsigned, unsigned> LineAndCol; +  const char *BufferID = "<unknown>"; +  std::string LineStr; +   +  if (Loc.isValid()) { +    int CurBuf = FindBufferContainingLoc(Loc); +    assert(CurBuf != -1 && "Invalid or unspecified location!"); + +    MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer; +    BufferID = CurMB->getBufferIdentifier(); -    // Translate from SMLoc ranges to column ranges. -    ColRanges.push_back(std::make_pair(R.Start.getPointer()-LineStart, -                                       R.End.getPointer()-LineStart)); +    // Scan backward to find the start of the line. +    const char *LineStart = Loc.getPointer(); +    const char *BufStart = CurMB->getBufferStart(); +    while (LineStart != BufStart && LineStart[-1] != '\n' && +           LineStart[-1] != '\r') +      --LineStart; + +    // Get the end of the line. +    const char *LineEnd = Loc.getPointer(); +    const char *BufEnd = CurMB->getBufferEnd(); +    while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r') +      ++LineEnd; +    LineStr = std::string(LineStart, LineEnd); + +    // Convert any ranges to column ranges that only intersect the line of the +    // location. +    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)); +    } + +    LineAndCol = getLineAndColumn(Loc, CurBuf);    } -   -  return SMDiagnostic(*this, Loc, -                      CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf), -                      Loc.getPointer()-LineStart, Kind, Msg.str(), +     +  return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first, +                      LineAndCol.second-1, Kind, Msg.str(),                        LineStr, ColRanges);  } @@ -205,9 +218,11 @@ void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind,    raw_ostream &OS = errs(); -  int CurBuf = FindBufferContainingLoc(Loc); -  assert(CurBuf != -1 && "Invalid or unspecified location!"); -  PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS); +  if (Loc != SMLoc()) { +    int CurBuf = FindBufferContainingLoc(Loc); +    assert(CurBuf != -1 && "Invalid or unspecified location!"); +    PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS); +  }    Diagnostic.print(0, OS, ShowColors);  } @@ -228,8 +243,8 @@ SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,  void SMDiagnostic::print(const char *ProgName, raw_ostream &S,                           bool ShowColors) const { -  // Display colors only if OS goes to a tty. -  ShowColors &= S.is_displayed(); +  // Display colors only if OS supports colors. +  ShowColors &= S.has_colors();    if (ShowColors)      S.changeColor(raw_ostream::SAVEDCOLOR, true); @@ -343,5 +358,3 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &S,    S << '\n';  } - - | 
