Coverage Report

Created: 2018-09-23 03:40

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h
Line
Count
Source (jump to first uncovered line)
1
//===- PreprocessorLexer.h - C Language Family Lexer ------------*- C++ -*-===//
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
/// \file
11
/// Defines the PreprocessorLexer interface.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
16
#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H
17
18
#include "clang/Lex/MultipleIncludeOpt.h"
19
#include "clang/Lex/Token.h"
20
#include "clang/Basic/SourceLocation.h"
21
#include "llvm/ADT/ArrayRef.h"
22
#include "llvm/ADT/SmallVector.h"
23
#include <cassert>
24
25
namespace clang {
26
27
class FileEntry;
28
class Preprocessor;
29
30
class PreprocessorLexer {
31
  virtual void anchor();
32
33
protected:
34
  friend class Preprocessor;
35
36
  // Preprocessor object controlling lexing.
37
  Preprocessor *PP = nullptr;
38
39
  /// The SourceManager FileID corresponding to the file being lexed.
40
  const FileID FID;
41
42
  /// Number of SLocEntries before lexing the file.
43
  unsigned InitialNumSLocEntries = 0;
44
45
  //===--------------------------------------------------------------------===//
46
  // Context-specific lexing flags set by the preprocessor.
47
  //===--------------------------------------------------------------------===//
48
49
  /// True when parsing \#XXX; turns '\\n' into a tok::eod token.
50
  bool ParsingPreprocessorDirective = false;
51
52
  /// True after \#include; turns \<xx> into a tok::angle_string_literal
53
  /// token.
54
  bool ParsingFilename = false;
55
56
  /// True if in raw mode.
57
  ///
58
  /// Raw mode disables interpretation of tokens and is a far faster mode to
59
  /// lex in than non-raw-mode.  This flag:
60
  ///  1. If EOF of the current lexer is found, the include stack isn't popped.
61
  ///  2. Identifier information is not looked up for identifier tokens.  As an
62
  ///     effect of this, implicit macro expansion is naturally disabled.
63
  ///  3. "#" tokens at the start of a line are treated as normal tokens, not
64
  ///     implicitly transformed by the lexer.
65
  ///  4. All diagnostic messages are disabled.
66
  ///  5. No callbacks are made into the preprocessor.
67
  ///
68
  /// Note that in raw mode that the PP pointer may be null.
69
  bool LexingRawMode = false;
70
71
  /// A state machine that detects the \#ifndef-wrapping a file
72
  /// idiom for the multiple-include optimization.
73
  MultipleIncludeOpt MIOpt;
74
75
  /// Information about the set of \#if/\#ifdef/\#ifndef blocks
76
  /// we are currently in.
77
  SmallVector<PPConditionalInfo, 4> ConditionalStack;
78
79
1.54M
  PreprocessorLexer() : FID() {}
80
  PreprocessorLexer(Preprocessor *pp, FileID fid);
81
2.13M
  virtual ~PreprocessorLexer() = default;
82
83
  virtual void IndirectLex(Token& Result) = 0;
84
85
  /// Return the source location for the next observable location.
86
  virtual SourceLocation getSourceLocation() = 0;
87
88
  //===--------------------------------------------------------------------===//
89
  // #if directive handling.
90
91
  /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
92
  /// what we are currently in for diagnostic emission (e.g. \#if with missing
93
  /// \#endif).
94
  void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
95
10.1M
                            bool FoundNonSkip, bool FoundElse) {
96
10.1M
    PPConditionalInfo CI;
97
10.1M
    CI.IfLoc = DirectiveStart;
98
10.1M
    CI.WasSkipping = WasSkipping;
99
10.1M
    CI.FoundNonSkip = FoundNonSkip;
100
10.1M
    CI.FoundElse = FoundElse;
101
10.1M
    ConditionalStack.push_back(CI);
102
10.1M
  }
103
0
  void pushConditionalLevel(const PPConditionalInfo &CI) {
104
0
    ConditionalStack.push_back(CI);
105
0
  }
106
107
  /// popConditionalLevel - Remove an entry off the top of the conditional
108
  /// stack, returning information about it.  If the conditional stack is empty,
109
  /// this returns true and does not fill in the arguments.
110
10.1M
  bool popConditionalLevel(PPConditionalInfo &CI) {
111
10.1M
    if (ConditionalStack.empty())
112
2
      return true;
113
10.1M
    CI = ConditionalStack.pop_back_val();
114
10.1M
    return false;
115
10.1M
  }
116
117
  /// Return the top of the conditional stack.
118
  /// \pre This requires that there be a conditional active.
119
4.23M
  PPConditionalInfo &peekConditionalLevel() {
120
4.23M
    assert(!ConditionalStack.empty() && "No conditionals active!");
121
4.23M
    return ConditionalStack.back();
122
4.23M
  }
123
124
10.1M
  unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
125
126
public:
127
  PreprocessorLexer(const PreprocessorLexer &) = delete;
128
  PreprocessorLexer &operator=(const PreprocessorLexer &) = delete;
129
130
  //===--------------------------------------------------------------------===//
131
  // Misc. lexing methods.
132
133
  /// After the preprocessor has parsed a \#include, lex and
134
  /// (potentially) macro expand the filename.
135
  ///
136
  /// If the sequence parsed is not lexically legal, emit a diagnostic and
137
  /// return a result EOD token.
138
  void LexIncludeFilename(Token &FilenameTok);
139
140
  /// Inform the lexer whether or not we are currently lexing a
141
  /// preprocessor directive.
142
33.7k
  void setParsingPreprocessorDirective(bool f) {
143
33.7k
    ParsingPreprocessorDirective = f;
144
33.7k
  }
145
146
  /// Return true if this lexer is in raw mode or not.
147
1.27G
  bool isLexingRawMode() const { return LexingRawMode; }
148
149
  /// Return the preprocessor object for this lexer.
150
0
  Preprocessor *getPP() const { return PP; }
151
152
2.92M
  FileID getFileID() const {
153
2.92M
    assert(PP &&
154
2.92M
      "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
155
2.92M
    return FID;
156
2.92M
  }
157
158
  /// Number of SLocEntries before lexing the file.
159
473k
  unsigned getInitialNumSLocEntries() const {
160
473k
    return InitialNumSLocEntries;
161
473k
  }
162
163
  /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
164
  /// getFileID(), this only works for lexers with attached preprocessors.
165
  const FileEntry *getFileEntry() const;
166
167
  /// Iterator that traverses the current stack of preprocessor
168
  /// conditional directives (\#if/\#ifdef/\#ifndef).
169
  using conditional_iterator =
170
      SmallVectorImpl<PPConditionalInfo>::const_iterator;
171
172
0
  conditional_iterator conditional_begin() const {
173
0
    return ConditionalStack.begin();
174
0
  }
175
176
0
  conditional_iterator conditional_end() const {
177
0
    return ConditionalStack.end();
178
0
  }
179
180
28
  void setConditionalLevels(ArrayRef<PPConditionalInfo> CL) {
181
28
    ConditionalStack.clear();
182
28
    ConditionalStack.append(CL.begin(), CL.end());
183
28
  }
184
};
185
186
} // namespace clang
187
188
#endif // LLVM_CLANG_LEX_PREPROCESSORLEXER_H