15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- ScratchBuffer.cpp - Scratch space for forming tokens -------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the ScratchBuffer interface. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/ScratchBuffer.h" 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceManager.h" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/MemoryBuffer.h" 1787cf5ac1b046a1db874b77dcb6e35f9c4b88c386Chris Lattner#include <cstring> 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// ScratchBufSize - The size of each chunk of scratch memory. Slightly less 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//than a page, almost certainly enough for anything. :) 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic const unsigned ScratchBufSize = 4060; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) { 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Set BytesUsed so that the first call to getToken will require an alloc. 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer BytesUsed = ScratchBufSize; 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getToken - Splat the specified text into a temporary MemoryBuffer and 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return a SourceLocation that refers to the token. This is just like the 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// method below, but returns a location that indicates the physloc of the 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// token. 3347246be8ac5b0ddde6c402b8fc6946b6135487b5Chris LattnerSourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len, 3447246be8ac5b0ddde6c402b8fc6946b6135487b5Chris Lattner const char *&DestPtr) { 352bc69bdb29c4912e90bd213608bd98e1fc73707aChris Lattner if (BytesUsed+Len+2 > ScratchBufSize) 362bc69bdb29c4912e90bd213608bd98e1fc73707aChris Lattner AllocScratchBuffer(Len+2); 372bc69bdb29c4912e90bd213608bd98e1fc73707aChris Lattner 382bc69bdb29c4912e90bd213608bd98e1fc73707aChris Lattner // Prefix the token with a \n, so that it looks like it is the first thing on 392bc69bdb29c4912e90bd213608bd98e1fc73707aChris Lattner // its own virtual line in caret diagnostics. 402bc69bdb29c4912e90bd213608bd98e1fc73707aChris Lattner CurBuffer[BytesUsed++] = '\n'; 411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4247246be8ac5b0ddde6c402b8fc6946b6135487b5Chris Lattner // Return a pointer to the character data. 4347246be8ac5b0ddde6c402b8fc6946b6135487b5Chris Lattner DestPtr = CurBuffer+BytesUsed; 441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Copy the token data into the buffer. 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer memcpy(CurBuffer+BytesUsed, Buf, Len); 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Remember that we used these bytes. 491fa495304c81e03f07f278a47b5efe9317104aabChris Lattner BytesUsed += Len+1; 501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 511fa495304c81e03f07f278a47b5efe9317104aabChris Lattner // Add a NUL terminator to the token. This keeps the tokens separated, in 521fa495304c81e03f07f278a47b5efe9317104aabChris Lattner // case they get relexed, and puts them on their own virtual lines in case a 531fa495304c81e03f07f278a47b5efe9317104aabChris Lattner // diagnostic points to one. 541fa495304c81e03f07f278a47b5efe9317104aabChris Lattner CurBuffer[BytesUsed-1] = '\0'; 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 56a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return BufferStartLoc.getLocWithOffset(BytesUsed-Len-1); 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) { 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Only pay attention to the requested length if it is larger than our default 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // page size. If it is, we allocate an entire chunk for it. This is to 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // support gigantic tokens, which almost certainly won't happen. :) 632bc69bdb29c4912e90bd213608bd98e1fc73707aChris Lattner if (RequestLen < ScratchBufSize) 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer RequestLen = ScratchBufSize; 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::MemoryBuffer *Buf = 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>"); 682b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner FileID FID = SourceMgr.createFileIDForMemBuffer(Buf); 692b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner BufferStartLoc = SourceMgr.getLocForStartOfFile(FID); 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurBuffer = const_cast<char*>(Buf->getBufferStart()); 711fa495304c81e03f07f278a47b5efe9317104aabChris Lattner BytesUsed = 1; 721fa495304c81e03f07f278a47b5efe9317104aabChris Lattner CurBuffer[0] = '0'; // Start out with a \0 for cleanliness. 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 74