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