PreprocessorLexer.h revision 344472ebeded2fca2ed5013b9e87f81d09bfa908
15208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
25208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI//
35208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI//                     The LLVM Compiler Infrastructure
45208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI//
55208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI// This file is distributed under the University of Illinois Open Source
65208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI// License. See LICENSE.TXT for details.
75208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI//
85208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI//===----------------------------------------------------------------------===//
95208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI///
105208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI/// \file
115208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI/// \brief Defines the PreprocessorLexer interface.
125208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI///
135208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI//===----------------------------------------------------------------------===//
145208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI
155208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI#ifndef LLVM_CLANG_PreprocessorLexer_H
165208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI#define LLVM_CLANG_PreprocessorLexer_H
175208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI
185208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI#include "clang/Lex/MultipleIncludeOpt.h"
193dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include "clang/Lex/Token.h"
200b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include "llvm/ADT/SmallVector.h"
2104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI
22aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardtnamespace clang {
23cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt
243dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAIclass FileEntry;
253dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAIclass Preprocessor;
260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI
270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIclass PreprocessorLexer {
280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI  virtual void anchor();
290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIprotected:
300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI  Preprocessor *PP;              // Preprocessor object controlling lexing.
310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI
3208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt  /// The SourceManager FileID corresponding to the file being lexed.
333dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI  const FileID FID;
345208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI
354e41854423b529d3107c23b85434d50a75d08057Jan Engelhardt  /// \brief Number of SLocEntries before lexing the file.
3677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  unsigned InitialNumSLocEntries;
3777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
38ef18e8147903885708d1c264904129af4fb636d6Jan Engelhardt  //===--------------------------------------------------------------------===//
393dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI  // Context-specific lexing flags set by the preprocessor.
405a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger  //===--------------------------------------------------------------------===//
415a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger
425a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger  /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
43c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt  bool ParsingPreprocessorDirective;
44c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt
45c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt  /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
46c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt  /// token.
47c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt  bool ParsingFilename;
48c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt
49c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt  /// \brief True if in raw mode.
50c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt  ///
5170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// Raw mode disables interpretation of tokens and is a far faster mode to
52c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt  /// lex in than non-raw-mode.  This flag:
535a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger  ///  1. If EOF of the current lexer is found, the include stack isn't popped.
540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI  ///  2. Identifier information is not looked up for identifier tokens.  As an
550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI  ///     effect of this, implicit macro expansion is naturally disabled.
560b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI  ///  3. "#" tokens at the start of a line are treated as normal tokens, not
570b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI  ///     implicitly transformed by the lexer.
580b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI  ///  4. All diagnostic messages are disabled.
590b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI  ///  5. No callbacks are made into the preprocessor.
608b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim  ///
618b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim  /// Note that in raw mode that the PP pointer may be null.
6240a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  bool LexingRawMode;
6340a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim
648b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim  /// \brief A state machine that detects the \#ifndef-wrapping a file
6540a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  /// idiom for the multiple-include optimization.
6640a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  MultipleIncludeOpt MIOpt;
6740a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim
6840a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks
6940a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  /// we are currently in.
7040a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  SmallVector<PPConditionalInfo, 4> ConditionalStack;
7140a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim
7240a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
7340a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
7440a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim  friend class Preprocessor;
7540a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim
768b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim  PreprocessorLexer(Preprocessor *pp, FileID fid);
77139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim
7884c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim  PreprocessorLexer()
79139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim    : PP(0), InitialNumSLocEntries(0),
80139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim      ParsingPreprocessorDirective(false),
81139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim      ParsingFilename(false),
8284c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim      LexingRawMode(false) {}
8384c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim
8484c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim  virtual ~PreprocessorLexer() {}
8584c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim
8684c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim  virtual void IndirectLex(Token& Result) = 0;
8770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim
8870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// \brief Return the source location for the next observable location.
8970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  virtual SourceLocation getSourceLocation() = 0;
9070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim
9170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  //===--------------------------------------------------------------------===//
9270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  // #if directive handling.
9370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim
9470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
9570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// what we are currently in for diagnostic emission (e.g. \#if with missing
9670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// \#endif).
9770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
9870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim                            bool FoundNonSkip, bool FoundElse) {
9970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    PPConditionalInfo CI;
100bddcb92d1f0f76d21c4469b1667c8199c9fab126Jan Engelhardt    CI.IfLoc = DirectiveStart;
10170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    CI.WasSkipping = WasSkipping;
10270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    CI.FoundNonSkip = FoundNonSkip;
10370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    CI.FoundElse = FoundElse;
10470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    ConditionalStack.push_back(CI);
10570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  }
10670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  void pushConditionalLevel(const PPConditionalInfo &CI) {
10770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    ConditionalStack.push_back(CI);
10870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  }
10970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim
11070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// popConditionalLevel - Remove an entry off the top of the conditional
11170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// stack, returning information about it.  If the conditional stack is empty,
11270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  /// this returns true and does not fill in the arguments.
11370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim  bool popConditionalLevel(PPConditionalInfo &CI) {
11470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    if (ConditionalStack.empty())
11570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim      return true;
11670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim    CI = ConditionalStack.pop_back_val();
117853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim    return false;
118853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim  }
119853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim
120853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim  /// \brief Return the top of the conditional stack.
121853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim  /// \pre This requires that there be a conditional active.
122853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim  PPConditionalInfo &peekConditionalLevel() {
123853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim    assert(!ConditionalStack.empty() && "No conditionals active!");
124853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim    return ConditionalStack.back();
125dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt  }
12677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
12777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
12877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
12977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtpublic:
13077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
13177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  //===--------------------------------------------------------------------===//
13277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  // Misc. lexing methods.
13377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
13477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// \brief After the preprocessor has parsed a \#include, lex and
13577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// (potentially) macro expand the filename.
13677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  ///
13777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// If the sequence parsed is not lexically legal, emit a diagnostic and
13877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// return a result EOD token.
13977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  void LexIncludeFilename(Token &Result);
14077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
14177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// \brief Inform the lexer whether or not we are currently lexing a
14277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// preprocessor directive.
14377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  void setParsingPreprocessorDirective(bool f) {
14477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt    ParsingPreprocessorDirective = f;
14577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  }
14677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
14777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// \brief Return true if this lexer is in raw mode or not.
14877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  bool isLexingRawMode() const { return LexingRawMode; }
14977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
15077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// \brief Return the preprocessor object for this lexer.
15177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  Preprocessor *getPP() const { return PP; }
15277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
15377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  FileID getFileID() const {
15477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt    assert(PP &&
15577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt      "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
15677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt    return FID;
15777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  }
15877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt
15977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  /// \brief Number of SLocEntries before lexing the file.
16077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  unsigned getInitialNumSLocEntries() const {
16177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt    return InitialNumSLocEntries;
16277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt  }
16339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt
16439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt  /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
1650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI  /// getFileID(), this only works for lexers with attached preprocessors.
1660b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI  const FileEntry *getFileEntry() const;
167c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt
1680b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI  /// \brief Iterator that traverses the current stack of preprocessor
1690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI  /// conditional directives (\#if/\#ifdef/\#ifndef).
1700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI  typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
1710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI    conditional_iterator;
1720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI
17339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt  conditional_iterator conditional_begin() const {
17439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt    return ConditionalStack.begin();
17539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt  }
17639bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt  conditional_iterator conditional_end() const {
17739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt    return ConditionalStack.end();
17839bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt  }
17939bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt};
18039bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt
18139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt}  // end namespace clang
18239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt
18339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt#endif
184ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt