blob: 20fb8a0c48041199fee26c6f28bf9621f7a3c46a [file] [log] [blame]
Ted Kremenek0e977de2008-11-12 21:33:59 +00001//===--- 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//===----------------------------------------------------------------------===//
James Dennett80b5a2f2012-06-20 00:48:54 +00009///
10/// \file
11/// \brief Defines the PreprocessorLexer interface.
12///
Ted Kremenek0e977de2008-11-12 21:33:59 +000013//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_PreprocessorLexer_H
16#define LLVM_CLANG_PreprocessorLexer_H
17
18#include "clang/Lex/MultipleIncludeOpt.h"
19#include "clang/Lex/Token.h"
Chris Lattner3a874a42009-01-18 02:52:26 +000020#include "llvm/ADT/SmallVector.h"
Mike Stump79d39f92009-09-09 13:12:01 +000021
Ted Kremenek0e977de2008-11-12 21:33:59 +000022namespace clang {
23
Daniel Dunbar0cc70f12010-03-30 17:57:47 +000024class FileEntry;
Ted Kremenek0e977de2008-11-12 21:33:59 +000025class Preprocessor;
26
27class PreprocessorLexer {
David Blaikie99ba9e32011-12-20 02:48:34 +000028 virtual void anchor();
Ted Kremenekd6a2e7d2008-11-12 23:13:54 +000029protected:
30 Preprocessor *PP; // Preprocessor object controlling lexing.
Ted Kremenek41938c82008-11-19 21:57:25 +000031
Chris Lattner2b2453a2009-01-17 06:22:33 +000032 /// The SourceManager FileID corresponding to the file being lexed.
33 const FileID FID;
Mike Stump1eb44332009-09-09 15:08:12 +000034
Argyrios Kyrtzidisd9d2b672011-08-21 23:33:04 +000035 /// \brief Number of SLocEntries before lexing the file.
36 unsigned InitialNumSLocEntries;
37
Ted Kremenekd6a2e7d2008-11-12 23:13:54 +000038 //===--------------------------------------------------------------------===//
Ted Kremenek0e977de2008-11-12 21:33:59 +000039 // Context-specific lexing flags set by the preprocessor.
Ted Kremenekd6a2e7d2008-11-12 23:13:54 +000040 //===--------------------------------------------------------------------===//
Mike Stump1eb44332009-09-09 15:08:12 +000041
James Dennett80b5a2f2012-06-20 00:48:54 +000042 /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
Ted Kremenek0e977de2008-11-12 21:33:59 +000043 bool ParsingPreprocessorDirective;
Mike Stump1eb44332009-09-09 15:08:12 +000044
James Dennett80b5a2f2012-06-20 00:48:54 +000045 /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
46 /// token.
Ted Kremenek0e977de2008-11-12 21:33:59 +000047 bool ParsingFilename;
Mike Stump1eb44332009-09-09 15:08:12 +000048
James Dennett80b5a2f2012-06-20 00:48:54 +000049 /// \brief True if in raw mode.
50 ///
51 /// Raw mode disables interpretation of tokens and is a far faster mode to
52 /// lex in than non-raw-mode. This flag:
Ted Kremenek0e977de2008-11-12 21:33:59 +000053 /// 1. If EOF of the current lexer is found, the include stack isn't popped.
54 /// 2. Identifier information is not looked up for identifier tokens. As an
55 /// effect of this, implicit macro expansion is naturally disabled.
56 /// 3. "#" tokens at the start of a line are treated as normal tokens, not
57 /// implicitly transformed by the lexer.
58 /// 4. All diagnostic messages are disabled.
59 /// 5. No callbacks are made into the preprocessor.
60 ///
61 /// Note that in raw mode that the PP pointer may be null.
62 bool LexingRawMode;
Mike Stump1eb44332009-09-09 15:08:12 +000063
James Dennett80b5a2f2012-06-20 00:48:54 +000064 /// \brief A state machine that detects the \#ifndef-wrapping a file
Ted Kremenek0e977de2008-11-12 21:33:59 +000065 /// idiom for the multiple-include optimization.
66 MultipleIncludeOpt MIOpt;
Mike Stump1eb44332009-09-09 15:08:12 +000067
James Dennett80b5a2f2012-06-20 00:48:54 +000068 /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks
Ted Kremenek0e977de2008-11-12 21:33:59 +000069 /// we are currently in.
Chris Lattner686775d2011-07-20 06:58:45 +000070 SmallVector<PPConditionalInfo, 4> ConditionalStack;
Mike Stump1eb44332009-09-09 15:08:12 +000071
Dmitri Gribenkof56faa02012-09-15 20:20:27 +000072 PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
73 void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
Ted Kremenek0e977de2008-11-12 21:33:59 +000074 friend class Preprocessor;
Mike Stump1eb44332009-09-09 15:08:12 +000075
Argyrios Kyrtzidisd9d2b672011-08-21 23:33:04 +000076 PreprocessorLexer(Preprocessor *pp, FileID fid);
Mike Stump1eb44332009-09-09 15:08:12 +000077
Ted Kremenek452e3782008-11-20 01:29:45 +000078 PreprocessorLexer()
Argyrios Kyrtzidisd9d2b672011-08-21 23:33:04 +000079 : PP(0), InitialNumSLocEntries(0),
Ted Kremenek452e3782008-11-20 01:29:45 +000080 ParsingPreprocessorDirective(false),
81 ParsingFilename(false),
Daniel Dunbar6e649732012-11-13 19:12:37 +000082 LexingRawMode(false) {}
Mike Stump1eb44332009-09-09 15:08:12 +000083
Chris Lattner2b2453a2009-01-17 06:22:33 +000084 virtual ~PreprocessorLexer() {}
Mike Stump1eb44332009-09-09 15:08:12 +000085
Ted Kremenekeb41c282008-11-12 22:46:33 +000086 virtual void IndirectLex(Token& Result) = 0;
Mike Stump1eb44332009-09-09 15:08:12 +000087
James Dennett80b5a2f2012-06-20 00:48:54 +000088 /// \brief Return the source location for the next observable location.
Ted Kremenekbc0f6bc2008-12-10 23:20:59 +000089 virtual SourceLocation getSourceLocation() = 0;
Mike Stump1eb44332009-09-09 15:08:12 +000090
Ted Kremenek0e977de2008-11-12 21:33:59 +000091 //===--------------------------------------------------------------------===//
92 // #if directive handling.
Mike Stump1eb44332009-09-09 15:08:12 +000093
James Dennett80b5a2f2012-06-20 00:48:54 +000094 /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
95 /// what we are currently in for diagnostic emission (e.g. \#if with missing
96 /// \#endif).
Ted Kremenek0e977de2008-11-12 21:33:59 +000097 void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
98 bool FoundNonSkip, bool FoundElse) {
99 PPConditionalInfo CI;
100 CI.IfLoc = DirectiveStart;
101 CI.WasSkipping = WasSkipping;
102 CI.FoundNonSkip = FoundNonSkip;
103 CI.FoundElse = FoundElse;
104 ConditionalStack.push_back(CI);
105 }
106 void pushConditionalLevel(const PPConditionalInfo &CI) {
107 ConditionalStack.push_back(CI);
Mike Stump1eb44332009-09-09 15:08:12 +0000108 }
109
Ted Kremenek0e977de2008-11-12 21:33:59 +0000110 /// popConditionalLevel - Remove an entry off the top of the conditional
111 /// stack, returning information about it. If the conditional stack is empty,
112 /// this returns true and does not fill in the arguments.
113 bool popConditionalLevel(PPConditionalInfo &CI) {
114 if (ConditionalStack.empty()) return true;
115 CI = ConditionalStack.back();
116 ConditionalStack.pop_back();
117 return false;
118 }
Mike Stump1eb44332009-09-09 15:08:12 +0000119
James Dennett80b5a2f2012-06-20 00:48:54 +0000120 /// \brief Return the top of the conditional stack.
121 /// \pre This requires that there be a conditional active.
Ted Kremenek0e977de2008-11-12 21:33:59 +0000122 PPConditionalInfo &peekConditionalLevel() {
123 assert(!ConditionalStack.empty() && "No conditionals active!");
124 return ConditionalStack.back();
125 }
Mike Stump1eb44332009-09-09 15:08:12 +0000126
127 unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
Ted Kremenek63db2a72008-11-26 00:57:02 +0000128
129public:
Mike Stump1eb44332009-09-09 15:08:12 +0000130
Ted Kremenekeb41c282008-11-12 22:46:33 +0000131 //===--------------------------------------------------------------------===//
132 // Misc. lexing methods.
Mike Stump1eb44332009-09-09 15:08:12 +0000133
James Dennett80b5a2f2012-06-20 00:48:54 +0000134 /// \brief After the preprocessor has parsed a \#include, lex and
135 /// (potentially) macro expand the filename.
136 ///
137 /// If the sequence parsed is not lexically legal, emit a diagnostic and
138 /// return a result EOD token.
Ted Kremenekeb41c282008-11-12 22:46:33 +0000139 void LexIncludeFilename(Token &Result);
Mike Stump1eb44332009-09-09 15:08:12 +0000140
James Dennett80b5a2f2012-06-20 00:48:54 +0000141 /// \brief Inform the lexer whether or not we are currently lexing a
142 /// preprocessor directive.
Ted Kremenek63db2a72008-11-26 00:57:02 +0000143 void setParsingPreprocessorDirective(bool f) {
144 ParsingPreprocessorDirective = f;
145 }
Mike Stump1eb44332009-09-09 15:08:12 +0000146
James Dennett80b5a2f2012-06-20 00:48:54 +0000147 /// \brief Return true if this lexer is in raw mode or not.
Chris Lattner74d15df2008-11-22 02:02:22 +0000148 bool isLexingRawMode() const { return LexingRawMode; }
149
James Dennett80b5a2f2012-06-20 00:48:54 +0000150 /// \brief Return the preprocessor object for this lexer.
Chris Lattner74d15df2008-11-22 02:02:22 +0000151 Preprocessor *getPP() const { return PP; }
Mike Stump1eb44332009-09-09 15:08:12 +0000152
153 FileID getFileID() const {
Ted Kremenek41938c82008-11-19 21:57:25 +0000154 assert(PP &&
155 "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
Chris Lattner2b2453a2009-01-17 06:22:33 +0000156 return FID;
Ted Kremenek41938c82008-11-19 21:57:25 +0000157 }
Mike Stump1eb44332009-09-09 15:08:12 +0000158
Argyrios Kyrtzidisd9d2b672011-08-21 23:33:04 +0000159 /// \brief Number of SLocEntries before lexing the file.
160 unsigned getInitialNumSLocEntries() const {
161 return InitialNumSLocEntries;
162 }
163
Chris Lattner2b2453a2009-01-17 06:22:33 +0000164 /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
165 /// getFileID(), this only works for lexers with attached preprocessors.
166 const FileEntry *getFileEntry() const;
Douglas Gregor6f2d1b12010-10-18 14:43:21 +0000167
168 /// \brief Iterator that traverses the current stack of preprocessor
James Dennett809d1be2012-06-13 22:07:09 +0000169 /// conditional directives (\#if/\#ifdef/\#ifndef).
Chris Lattner686775d2011-07-20 06:58:45 +0000170 typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
Douglas Gregor6f2d1b12010-10-18 14:43:21 +0000171 conditional_iterator;
172
173 conditional_iterator conditional_begin() const {
174 return ConditionalStack.begin();
175 }
176 conditional_iterator conditional_end() const {
177 return ConditionalStack.end();
178 }
Ted Kremenek0e977de2008-11-12 21:33:59 +0000179};
180
181} // end namespace clang
182
183#endif