LLVM API Documentation
00001 //===-- SourceFile.cpp - SourceFile implementation for the debugger -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the SourceFile class for the LLVM debugger. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Debugger/SourceFile.h" 00015 #include "llvm/Support/MemoryBuffer.h" 00016 #include <cassert> 00017 using namespace llvm; 00018 00019 static const char EmptyFile = 0; 00020 00021 SourceFile::SourceFile(const std::string &fn, const GlobalVariable *Desc) 00022 : Filename(fn), Descriptor(Desc) { 00023 File.reset(MemoryBuffer::getFileOrSTDIN(fn)); 00024 00025 // On error, return an empty buffer. 00026 if (File == 0) 00027 File.reset(MemoryBuffer::getMemBuffer(&EmptyFile, &EmptyFile)); 00028 } 00029 00030 SourceFile::~SourceFile() { 00031 } 00032 00033 00034 /// calculateLineOffsets - Compute the LineOffset vector for the current file. 00035 /// 00036 void SourceFile::calculateLineOffsets() const { 00037 assert(LineOffset.empty() && "Line offsets already computed!"); 00038 const char *BufPtr = File->getBufferStart(); 00039 const char *FileStart = BufPtr; 00040 const char *FileEnd = File->getBufferEnd(); 00041 do { 00042 LineOffset.push_back(BufPtr-FileStart); 00043 00044 // Scan until we get to a newline. 00045 while (BufPtr != FileEnd && *BufPtr != '\n' && *BufPtr != '\r') 00046 ++BufPtr; 00047 00048 if (BufPtr != FileEnd) { 00049 ++BufPtr; // Skip over the \n or \r 00050 if (BufPtr[-1] == '\r' && BufPtr != FileEnd && BufPtr[0] == '\n') 00051 ++BufPtr; // Skip over dos/windows style \r\n's 00052 } 00053 } while (BufPtr != FileEnd); 00054 } 00055 00056 00057 /// getSourceLine - Given a line number, return the start and end of the line 00058 /// in the file. If the line number is invalid, or if the file could not be 00059 /// loaded, null pointers are returned for the start and end of the file. Note 00060 /// that line numbers start with 0, not 1. 00061 void SourceFile::getSourceLine(unsigned LineNo, const char *&LineStart, 00062 const char *&LineEnd) const { 00063 LineStart = LineEnd = 0; 00064 if (LineOffset.empty()) calculateLineOffsets(); 00065 00066 // Asking for an out-of-range line number? 00067 if (LineNo >= LineOffset.size()) return; 00068 00069 // Otherwise, they are asking for a valid line, which we can fulfill. 00070 LineStart = File->getBufferStart()+LineOffset[LineNo]; 00071 00072 if (LineNo+1 < LineOffset.size()) 00073 LineEnd = File->getBufferStart()+LineOffset[LineNo+1]; 00074 else 00075 LineEnd = File->getBufferEnd(); 00076 00077 // If the line ended with a newline, strip it off. 00078 while (LineEnd != LineStart && (LineEnd[-1] == '\n' || LineEnd[-1] == '\r')) 00079 --LineEnd; 00080 00081 assert(LineEnd >= LineStart && "We somehow got our pointers swizzled!"); 00082 }