 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
68.8% |
22 / 32 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
32 / 32 |
| |
|
Line Coverage: |
100.0% |
52 / 52 |
| |
 |
|
 |
1 : //===--- PPCaching.cpp - Handle caching lexed tokens ----------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements pieces of the Preprocessor interface that manage the
11 : // caching of lexed tokens.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "clang/Lex/Preprocessor.h"
16 : using namespace clang;
17 :
18 : /// EnableBacktrackAtThisPos - From the point that this method is called, and
19 : /// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
20 : /// keeps track of the lexed tokens so that a subsequent Backtrack() call will
21 : /// make the Preprocessor re-lex the same tokens.
22 : ///
23 : /// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
24 : /// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
25 : /// be combined with the EnableBacktrackAtThisPos calls in reverse order.
26 5985: void Preprocessor::EnableBacktrackAtThisPos() {
27 5985: BacktrackPositions.push_back(CachedLexPos);
28 5985: EnterCachingLexMode();
29 5985: }
30 :
31 : /// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
32 83: void Preprocessor::CommitBacktrackedTokens() {
33 : assert(!BacktrackPositions.empty()
83: branch 1 taken
0: branch 2 not taken
34 83: && "EnableBacktrackAtThisPos was not called!");
35 83: BacktrackPositions.pop_back();
36 83: }
37 :
38 : /// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
39 : /// EnableBacktrackAtThisPos() was previously called.
40 5902: void Preprocessor::Backtrack() {
41 : assert(!BacktrackPositions.empty()
5902: branch 1 taken
0: branch 2 not taken
42 5902: && "EnableBacktrackAtThisPos was not called!");
43 5902: CachedLexPos = BacktrackPositions.back();
44 5902: BacktrackPositions.pop_back();
45 5902: }
46 :
47 134893: void Preprocessor::CachingLex(Token &Result) {
74590: branch 1 taken
60303: branch 2 taken
48 134893: if (CachedLexPos < CachedTokens.size()) {
49 74590: Result = CachedTokens[CachedLexPos++];
50 74590: return;
51 : }
52 :
53 60303: ExitCachingLexMode();
54 60303: Lex(Result);
55 :
52665: branch 1 taken
7638: branch 2 taken
56 60303: if (!isBacktrackEnabled()) {
57 : // All cached tokens were consumed.
58 52665: CachedTokens.clear();
59 52665: CachedLexPos = 0;
60 52665: return;
61 : }
62 :
63 : // We should cache the lexed token.
64 :
65 7638: EnterCachingLexMode();
7638: branch 1 taken
0: branch 2 not taken
66 7638: if (Result.isNot(tok::eof)) {
67 7638: CachedTokens.push_back(Result);
68 7638: ++CachedLexPos;
69 : }
70 : }
71 :
72 78489: void Preprocessor::EnterCachingLexMode() {
6556: branch 1 taken
71933: branch 2 taken
73 78489: if (InCachingLexMode())
74 6556: return;
75 :
76 71933: PushIncludeMacroStack();
77 : }
78 :
79 :
80 63436: const Token &Preprocessor::PeekAhead(unsigned N) {
63436: branch 1 taken
0: branch 2 not taken
81 63436: assert(CachedLexPos + N > CachedTokens.size() && "Confused caching.");
82 63436: ExitCachingLexMode();
63436: branch 1 taken
63436: branch 2 taken
83 126872: for (unsigned C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
84 63436: CachedTokens.push_back(Token());
85 63436: Lex(CachedTokens.back());
86 : }
87 63436: EnterCachingLexMode();
88 63436: return CachedTokens.back();
89 : }
90 :
91 1549: void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) {
1549: branch 1 taken
0: branch 2 not taken
92 1549: assert(Tok.isAnnotation() && "Expected annotation token");
0: branch 0 not taken
1549: branch 1 taken
93 1549: assert(CachedLexPos != 0 && "Expected to have some cached tokens");
94 : assert(CachedTokens[CachedLexPos-1].getLastLoc() == Tok.getAnnotationEndLoc()
1549: branch 4 taken
0: branch 5 not taken
95 1549: && "The annotation should be until the most recent cached token");
96 :
97 : // Start from the end of the cached tokens list and look for the token
98 : // that is the beginning of the annotation token.
2404: branch 0 taken
0: branch 1 not taken
99 2404: for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) {
100 2404: CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1;
1549: branch 3 taken
855: branch 4 taken
101 2404: if (AnnotBegin->getLocation() == Tok.getLocation()) {
102 : assert((BacktrackPositions.empty() || BacktrackPositions.back() < i) &&
1549: branch 1 taken
0: branch 2 not taken
1549: branch 4 taken
0: branch 5 not taken
103 1549: "The backtrack pos points inside the annotated tokens!");
104 : // Replace the cached tokens with the single annotation token.
309: branch 0 taken
1240: branch 1 taken
105 1549: if (i < CachedLexPos)
106 309: CachedTokens.erase(AnnotBegin + 1, CachedTokens.begin() + CachedLexPos);
107 1549: *AnnotBegin = Tok;
108 1549: CachedLexPos = i;
109 1549: return;
110 : }
111 : }
112 : }
Generated: 2010-02-10 01:31 by zcov