/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Lex/ScratchBuffer.cpp
Line | Count | Source |
1 | | //===--- ScratchBuffer.cpp - Scratch space for forming tokens -------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file implements the ScratchBuffer interface. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "clang/Lex/ScratchBuffer.h" |
14 | | #include "clang/Basic/SourceManager.h" |
15 | | #include "llvm/Support/MemoryBuffer.h" |
16 | | #include <cstring> |
17 | | using namespace clang; |
18 | | |
19 | | // ScratchBufSize - The size of each chunk of scratch memory. Slightly less |
20 | | //than a page, almost certainly enough for anything. :) |
21 | | static const unsigned ScratchBufSize = 4060; |
22 | | |
23 | | ScratchBuffer::ScratchBuffer(SourceManager &SM) |
24 | 93.7k | : SourceMgr(SM), CurBuffer(nullptr) { |
25 | | // Set BytesUsed so that the first call to getToken will require an alloc. |
26 | 93.7k | BytesUsed = ScratchBufSize; |
27 | 93.7k | } |
28 | | |
29 | | /// getToken - Splat the specified text into a temporary MemoryBuffer and |
30 | | /// return a SourceLocation that refers to the token. This is just like the |
31 | | /// method below, but returns a location that indicates the physloc of the |
32 | | /// token. |
33 | | SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len, |
34 | 12.3M | const char *&DestPtr) { |
35 | 12.3M | if (BytesUsed+Len+2 > ScratchBufSize) |
36 | 80.6k | AllocScratchBuffer(Len+2); |
37 | 12.3M | else { |
38 | | // Clear out the source line cache if it's already been computed. |
39 | | // FIXME: Allow this to be incrementally extended. |
40 | 12.3M | SourceMgr.getSLocEntry(SourceMgr.getFileID(BufferStartLoc)) |
41 | 12.3M | .getFile() |
42 | 12.3M | .getContentCache() |
43 | 12.3M | .SourceLineCache = SrcMgr::LineOffsetMapping(); |
44 | 12.3M | } |
45 | | |
46 | | // Prefix the token with a \n, so that it looks like it is the first thing on |
47 | | // its own virtual line in caret diagnostics. |
48 | 12.3M | CurBuffer[BytesUsed++] = '\n'; |
49 | | |
50 | | // Return a pointer to the character data. |
51 | 12.3M | DestPtr = CurBuffer+BytesUsed; |
52 | | |
53 | | // Copy the token data into the buffer. |
54 | 12.3M | memcpy(CurBuffer+BytesUsed, Buf, Len); |
55 | | |
56 | | // Remember that we used these bytes. |
57 | 12.3M | BytesUsed += Len+1; |
58 | | |
59 | | // Add a NUL terminator to the token. This keeps the tokens separated, in |
60 | | // case they get relexed, and puts them on their own virtual lines in case a |
61 | | // diagnostic points to one. |
62 | 12.3M | CurBuffer[BytesUsed-1] = '\0'; |
63 | | |
64 | 12.3M | return BufferStartLoc.getLocWithOffset(BytesUsed-Len-1); |
65 | 12.3M | } |
66 | | |
67 | 80.6k | void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) { |
68 | | // Only pay attention to the requested length if it is larger than our default |
69 | | // page size. If it is, we allocate an entire chunk for it. This is to |
70 | | // support gigantic tokens, which almost certainly won't happen. :) |
71 | 80.6k | if (RequestLen < ScratchBufSize) |
72 | 80.6k | RequestLen = ScratchBufSize; |
73 | | |
74 | | // Get scratch buffer. Zero-initialize it so it can be dumped into a PCH file |
75 | | // deterministically. |
76 | 80.6k | std::unique_ptr<llvm::WritableMemoryBuffer> OwnBuf = |
77 | 80.6k | llvm::WritableMemoryBuffer::getNewMemBuffer(RequestLen, |
78 | 80.6k | "<scratch space>"); |
79 | 80.6k | CurBuffer = OwnBuf->getBufferStart(); |
80 | 80.6k | FileID FID = SourceMgr.createFileID(std::move(OwnBuf)); |
81 | 80.6k | BufferStartLoc = SourceMgr.getLocForStartOfFile(FID); |
82 | 80.6k | BytesUsed = 0; |
83 | 80.6k | } |