Coverage Report

Created: 2018-07-19 20:53

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Rewrite/TokenRewriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- TokenRewriter.cpp - Token-based code rewriting interface -----------===//
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 the TokenRewriter class, which is used for code
11
//  transformations.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "clang/Rewrite/Core/TokenRewriter.h"
16
#include "clang/Basic/SourceManager.h"
17
#include "clang/Lex/Lexer.h"
18
#include "clang/Lex/ScratchBuffer.h"
19
#include "clang/Lex/Token.h"
20
#include <cassert>
21
#include <cstring>
22
#include <map>
23
#include <utility>
24
25
using namespace clang;
26
27
TokenRewriter::TokenRewriter(FileID FID, SourceManager &SM,
28
0
                             const LangOptions &LangOpts) {
29
0
  ScratchBuf.reset(new ScratchBuffer(SM));
30
0
31
0
  // Create a lexer to lex all the tokens of the main file in raw mode.
32
0
  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
33
0
  Lexer RawLex(FID, FromFile, SM, LangOpts);
34
0
35
0
  // Return all comments and whitespace as tokens.
36
0
  RawLex.SetKeepWhitespaceMode(true);
37
0
38
0
  // Lex the file, populating our datastructures.
39
0
  Token RawTok;
40
0
  RawLex.LexFromRawLexer(RawTok);
41
0
  while (RawTok.isNot(tok::eof)) {
42
#if 0
43
    if (Tok.is(tok::raw_identifier)) {
44
      // Look up the identifier info for the token.  This should use
45
      // IdentifierTable directly instead of PP.
46
      PP.LookUpIdentifierInfo(Tok);
47
    }
48
#endif
49
50
0
    AddToken(RawTok, TokenList.end());
51
0
    RawLex.LexFromRawLexer(RawTok);
52
0
  }
53
0
}
54
55
0
TokenRewriter::~TokenRewriter() = default;
56
57
/// RemapIterator - Convert from token_iterator (a const iterator) to
58
/// TokenRefTy (a non-const iterator).
59
0
TokenRewriter::TokenRefTy TokenRewriter::RemapIterator(token_iterator I) {
60
0
  if (I == token_end()) return TokenList.end();
61
0
62
0
  // FIXME: This is horrible, we should use our own list or something to avoid
63
0
  // this.
64
0
  std::map<SourceLocation, TokenRefTy>::iterator MapIt =
65
0
    TokenAtLoc.find(I->getLocation());
66
0
  assert(MapIt != TokenAtLoc.end() && "iterator not in rewriter?");
67
0
  return MapIt->second;
68
0
}
69
70
/// AddToken - Add the specified token into the Rewriter before the other
71
/// position.
72
TokenRewriter::TokenRefTy
73
0
TokenRewriter::AddToken(const Token &T, TokenRefTy Where) {
74
0
  Where = TokenList.insert(Where, T);
75
0
76
0
  bool InsertSuccess = TokenAtLoc.insert(std::make_pair(T.getLocation(),
77
0
                                                        Where)).second;
78
0
  assert(InsertSuccess && "Token location already in rewriter!");
79
0
  (void)InsertSuccess;
80
0
  return Where;
81
0
}
82
83
TokenRewriter::token_iterator
84
0
TokenRewriter::AddTokenBefore(token_iterator I, const char *Val) {
85
0
  unsigned Len = strlen(Val);
86
0
87
0
  // Plop the string into the scratch buffer, then create a token for this
88
0
  // string.
89
0
  Token Tok;
90
0
  Tok.startToken();
91
0
  const char *Spelling;
92
0
  Tok.setLocation(ScratchBuf->getToken(Val, Len, Spelling));
93
0
  Tok.setLength(Len);
94
0
95
0
  // TODO: Form a whole lexer around this and relex the token!  For now, just
96
0
  // set kind to tok::unknown.
97
0
  Tok.setKind(tok::unknown);
98
0
99
0
  return AddToken(Tok, RemapIterator(I));
100
0
}