ScratchBuffer.cpp revision 226633
1243789Sdim//===--- ScratchBuffer.cpp - Scratch space for forming tokens -------------===// 2243789Sdim// 3243789Sdim// The LLVM Compiler Infrastructure 4243789Sdim// 5243789Sdim// This file is distributed under the University of Illinois Open Source 6243789Sdim// License. See LICENSE.TXT for details. 7243789Sdim// 8243789Sdim//===----------------------------------------------------------------------===// 9243789Sdim// 10243789Sdim// This file implements the ScratchBuffer interface. 11251662Sdim// 12251662Sdim//===----------------------------------------------------------------------===// 13251662Sdim 14243789Sdim#include "clang/Lex/ScratchBuffer.h" 15249423Sdim#include "clang/Basic/SourceManager.h" 16243789Sdim#include "llvm/Support/MemoryBuffer.h" 17243789Sdim#include <cstring> 18243789Sdimusing namespace clang; 19243789Sdim 20243789Sdim// ScratchBufSize - The size of each chunk of scratch memory. Slightly less 21243789Sdim//than a page, almost certainly enough for anything. :) 22243789Sdimstatic const unsigned ScratchBufSize = 4060; 23249423Sdim 24243789SdimScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) { 25243789Sdim // Set BytesUsed so that the first call to getToken will require an alloc. 26243789Sdim BytesUsed = ScratchBufSize; 27243789Sdim} 28249423Sdim 29243789Sdim/// getToken - Splat the specified text into a temporary MemoryBuffer and 30243789Sdim/// return a SourceLocation that refers to the token. This is just like the 31243789Sdim/// method below, but returns a location that indicates the physloc of the 32243789Sdim/// token. 33243789SdimSourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len, 34243789Sdim const char *&DestPtr) { 35249423Sdim if (BytesUsed+Len+2 > ScratchBufSize) 36243789Sdim AllocScratchBuffer(Len+2); 37288943Sdim 38288943Sdim // Prefix the token with a \n, so that it looks like it is the first thing on 39288943Sdim // its own virtual line in caret diagnostics. 40288943Sdim CurBuffer[BytesUsed++] = '\n'; 41243789Sdim 42243789Sdim // Return a pointer to the character data. 43243789Sdim DestPtr = CurBuffer+BytesUsed; 44249423Sdim 45249423Sdim // Copy the token data into the buffer. 46249423Sdim memcpy(CurBuffer+BytesUsed, Buf, Len); 47243789Sdim 48249423Sdim // Remember that we used these bytes. 49249423Sdim BytesUsed += Len+1; 50249423Sdim 51261991Sdim // Add a NUL terminator to the token. This keeps the tokens separated, in 52249423Sdim // case they get relexed, and puts them on their own virtual lines in case a 53261991Sdim // diagnostic points to one. 54249423Sdim CurBuffer[BytesUsed-1] = '\0'; 55249423Sdim 56243789Sdim return BufferStartLoc.getLocWithOffset(BytesUsed-Len-1); 57276479Sdim} 58243789Sdim 59243789Sdimvoid ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) { 60296417Sdim // Only pay attention to the requested length if it is larger than our default 61276479Sdim // page size. If it is, we allocate an entire chunk for it. This is to 62280031Sdim // support gigantic tokens, which almost certainly won't happen. :) 63276479Sdim if (RequestLen < ScratchBufSize) 64280031Sdim RequestLen = ScratchBufSize; 65296417Sdim 66296417Sdim llvm::MemoryBuffer *Buf = 67288943Sdim llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>"); 68249423Sdim FileID FID = SourceMgr.createFileIDForMemBuffer(Buf); 69249423Sdim BufferStartLoc = SourceMgr.getLocForStartOfFile(FID); 70249423Sdim CurBuffer = const_cast<char*>(Buf->getBufferStart()); 71243789Sdim BytesUsed = 1; 72249423Sdim CurBuffer[0] = '0'; // Start out with a \0 for cleanliness. 73243789Sdim} 74249423Sdim