On 64bit we may have a personality function which requires 64 bits to
[oota-llvm.git] / lib / Debugger / SourceFile.cpp
1 //===-- SourceFile.cpp - SourceFile implementation for the debugger -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the SourceFile class for the LLVM debugger.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Debugger/SourceFile.h"
15 #include "llvm/Support/MemoryBuffer.h"
16 #include <cassert>
17 using namespace llvm;
18
19 static const char EmptyFile = 0;
20
21 SourceFile::SourceFile(const std::string &fn, const GlobalVariable *Desc)
22   : Filename(fn), Descriptor(Desc) {
23   File.reset(MemoryBuffer::getFileOrSTDIN(fn));
24     
25   // On error, return an empty buffer.
26   if (File == 0)
27     File.reset(MemoryBuffer::getMemBuffer(&EmptyFile, &EmptyFile));
28 }
29
30 SourceFile::~SourceFile() {
31 }
32
33
34 /// calculateLineOffsets - Compute the LineOffset vector for the current file.
35 ///
36 void SourceFile::calculateLineOffsets() const {
37   assert(LineOffset.empty() && "Line offsets already computed!");
38   const char *BufPtr = File->getBufferStart();
39   const char *FileStart = BufPtr;
40   const char *FileEnd = File->getBufferEnd();
41   do {
42     LineOffset.push_back(BufPtr-FileStart);
43
44     // Scan until we get to a newline.
45     while (BufPtr != FileEnd && *BufPtr != '\n' && *BufPtr != '\r')
46       ++BufPtr;
47
48     if (BufPtr != FileEnd) {
49       ++BufPtr;               // Skip over the \n or \r
50       if (BufPtr[-1] == '\r' && BufPtr != FileEnd && BufPtr[0] == '\n')
51         ++BufPtr;   // Skip over dos/windows style \r\n's
52     }
53   } while (BufPtr != FileEnd);
54 }
55
56
57 /// getSourceLine - Given a line number, return the start and end of the line
58 /// in the file.  If the line number is invalid, or if the file could not be
59 /// loaded, null pointers are returned for the start and end of the file. Note
60 /// that line numbers start with 0, not 1.
61 void SourceFile::getSourceLine(unsigned LineNo, const char *&LineStart,
62                                const char *&LineEnd) const {
63   LineStart = LineEnd = 0;
64   if (LineOffset.empty()) calculateLineOffsets();
65
66   // Asking for an out-of-range line number?
67   if (LineNo >= LineOffset.size()) return;
68
69   // Otherwise, they are asking for a valid line, which we can fulfill.
70   LineStart = File->getBufferStart()+LineOffset[LineNo];
71
72   if (LineNo+1 < LineOffset.size())
73     LineEnd = File->getBufferStart()+LineOffset[LineNo+1];
74   else
75     LineEnd = File->getBufferEnd();
76
77   // If the line ended with a newline, strip it off.
78   while (LineEnd != LineStart && (LineEnd[-1] == '\n' || LineEnd[-1] == '\r'))
79     --LineEnd;
80
81   assert(LineEnd >= LineStart && "We somehow got our pointers swizzled!");
82 }