Path: blob/main/contrib/llvm-project/clang/lib/Lex/ScratchBuffer.cpp
35233 views
//===--- ScratchBuffer.cpp - Scratch space for forming tokens -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the ScratchBuffer interface.9//10//===----------------------------------------------------------------------===//1112#include "clang/Lex/ScratchBuffer.h"13#include "clang/Basic/SourceManager.h"14#include "llvm/Support/MemoryBuffer.h"15#include <cstring>16using namespace clang;1718// ScratchBufSize - The size of each chunk of scratch memory. Slightly less19//than a page, almost certainly enough for anything. :)20static const unsigned ScratchBufSize = 4060;2122ScratchBuffer::ScratchBuffer(SourceManager &SM)23: SourceMgr(SM), CurBuffer(nullptr) {24// Set BytesUsed so that the first call to getToken will require an alloc.25BytesUsed = ScratchBufSize;26}2728/// getToken - Splat the specified text into a temporary MemoryBuffer and29/// return a SourceLocation that refers to the token. This is just like the30/// method below, but returns a location that indicates the physloc of the31/// token.32SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len,33const char *&DestPtr) {34if (BytesUsed+Len+2 > ScratchBufSize)35AllocScratchBuffer(Len+2);36else {37// Clear out the source line cache if it's already been computed.38// FIXME: Allow this to be incrementally extended.39SourceMgr.getSLocEntry(SourceMgr.getFileID(BufferStartLoc))40.getFile()41.getContentCache()42.SourceLineCache = SrcMgr::LineOffsetMapping();43}4445// Prefix the token with a \n, so that it looks like it is the first thing on46// its own virtual line in caret diagnostics.47CurBuffer[BytesUsed++] = '\n';4849// Return a pointer to the character data.50DestPtr = CurBuffer+BytesUsed;5152// Copy the token data into the buffer.53memcpy(CurBuffer+BytesUsed, Buf, Len);5455// Remember that we used these bytes.56BytesUsed += Len+1;5758// Add a NUL terminator to the token. This keeps the tokens separated, in59// case they get relexed, and puts them on their own virtual lines in case a60// diagnostic points to one.61CurBuffer[BytesUsed-1] = '\0';6263return BufferStartLoc.getLocWithOffset(BytesUsed-Len-1);64}6566void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) {67// Only pay attention to the requested length if it is larger than our default68// page size. If it is, we allocate an entire chunk for it. This is to69// support gigantic tokens, which almost certainly won't happen. :)70if (RequestLen < ScratchBufSize)71RequestLen = ScratchBufSize;7273// Get scratch buffer. Zero-initialize it so it can be dumped into a PCH file74// deterministically.75std::unique_ptr<llvm::WritableMemoryBuffer> OwnBuf =76llvm::WritableMemoryBuffer::getNewMemBuffer(RequestLen,77"<scratch space>");78CurBuffer = OwnBuf->getBufferStart();79FileID FID = SourceMgr.createFileID(std::move(OwnBuf));80BufferStartLoc = SourceMgr.getLocForStartOfFile(FID);81BytesUsed = 0;82}838485