PreprocessorLexer.h revision 344472ebeded2fca2ed5013b9e87f81d09bfa908
10e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
20e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek//
30e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek//                     The LLVM Compiler Infrastructure
40e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek//
50e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek// This file is distributed under the University of Illinois Open Source
60e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek// License. See LICENSE.TXT for details.
70e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek//
80e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek//===----------------------------------------------------------------------===//
980b5a2fea27561dce90c7588181185130d61e55eJames Dennett///
1080b5a2fea27561dce90c7588181185130d61e55eJames Dennett/// \file
1180b5a2fea27561dce90c7588181185130d61e55eJames Dennett/// \brief Defines the PreprocessorLexer interface.
1280b5a2fea27561dce90c7588181185130d61e55eJames Dennett///
130e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek//===----------------------------------------------------------------------===//
140e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek
150e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek#ifndef LLVM_CLANG_PreprocessorLexer_H
160e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek#define LLVM_CLANG_PreprocessorLexer_H
170e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek
180e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek#include "clang/Lex/MultipleIncludeOpt.h"
190e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek#include "clang/Lex/Token.h"
203a874a405d1913b132e4ecfa52e22c4e2264b05dChris Lattner#include "llvm/ADT/SmallVector.h"
2179d39f92590cf2e91bf81486b02cd1156d13ca54Mike Stump
220e977de1eacfbc143bdedad87c14b53814159023Ted Kremeneknamespace clang {
230e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek
240cc70f1586874aed3337c57cb255b112cdac0948Daniel Dunbarclass FileEntry;
250e977de1eacfbc143bdedad87c14b53814159023Ted Kremenekclass Preprocessor;
260e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek
270e977de1eacfbc143bdedad87c14b53814159023Ted Kremenekclass PreprocessorLexer {
2899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
29d6a2e7d71e9a910c45a3eb0268a5d94635003d58Ted Kremenekprotected:
30d6a2e7d71e9a910c45a3eb0268a5d94635003d58Ted Kremenek  Preprocessor *PP;              // Preprocessor object controlling lexing.
3141938c8493b4380df738263166b746eacb33c309Ted Kremenek
322b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  /// The SourceManager FileID corresponding to the file being lexed.
332b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  const FileID FID;
341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
35d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis  /// \brief Number of SLocEntries before lexing the file.
36d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis  unsigned InitialNumSLocEntries;
37d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis
38d6a2e7d71e9a910c45a3eb0268a5d94635003d58Ted Kremenek  //===--------------------------------------------------------------------===//
390e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  // Context-specific lexing flags set by the preprocessor.
40d6a2e7d71e9a910c45a3eb0268a5d94635003d58Ted Kremenek  //===--------------------------------------------------------------------===//
411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4280b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
430e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  bool ParsingPreprocessorDirective;
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4580b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
4680b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// token.
470e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  bool ParsingFilename;
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4980b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief True if in raw mode.
5080b5a2fea27561dce90c7588181185130d61e55eJames Dennett  ///
5180b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// Raw mode disables interpretation of tokens and is a far faster mode to
5280b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// lex in than non-raw-mode.  This flag:
530e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///  1. If EOF of the current lexer is found, the include stack isn't popped.
540e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///  2. Identifier information is not looked up for identifier tokens.  As an
550e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///     effect of this, implicit macro expansion is naturally disabled.
560e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///  3. "#" tokens at the start of a line are treated as normal tokens, not
570e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///     implicitly transformed by the lexer.
580e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///  4. All diagnostic messages are disabled.
590e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///  5. No callbacks are made into the preprocessor.
600e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  ///
610e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  /// Note that in raw mode that the PP pointer may be null.
620e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  bool LexingRawMode;
631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6480b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief A state machine that detects the \#ifndef-wrapping a file
650e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  /// idiom for the multiple-include optimization.
660e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  MultipleIncludeOpt MIOpt;
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6880b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks
690e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  /// we are currently in.
70686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<PPConditionalInfo, 4> ConditionalStack;
711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
73f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
740e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  friend class Preprocessor;
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
76d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis  PreprocessorLexer(Preprocessor *pp, FileID fid);
771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
78452e37837a48b2f0ced144784277fd4d28cbede9Ted Kremenek  PreprocessorLexer()
79d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis    : PP(0), InitialNumSLocEntries(0),
80452e37837a48b2f0ced144784277fd4d28cbede9Ted Kremenek      ParsingPreprocessorDirective(false),
81452e37837a48b2f0ced144784277fd4d28cbede9Ted Kremenek      ParsingFilename(false),
826e649737898ffb627c377fd8fa0a437d0a42ae4aDaniel Dunbar      LexingRawMode(false) {}
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
842b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  virtual ~PreprocessorLexer() {}
851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
86eb41c28b78634ba2165b4aa04e33f3a12e590b0eTed Kremenek  virtual void IndirectLex(Token& Result) = 0;
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8880b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief Return the source location for the next observable location.
89bc0f6bc0391ecdff331885cdc769c20b2cb628a6Ted Kremenek  virtual SourceLocation getSourceLocation() = 0;
901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
910e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  //===--------------------------------------------------------------------===//
920e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  // #if directive handling.
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9480b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
9580b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// what we are currently in for diagnostic emission (e.g. \#if with missing
9680b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \#endif).
970e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
980e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek                            bool FoundNonSkip, bool FoundElse) {
990e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    PPConditionalInfo CI;
1000e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    CI.IfLoc = DirectiveStart;
1010e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    CI.WasSkipping = WasSkipping;
1020e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    CI.FoundNonSkip = FoundNonSkip;
1030e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    CI.FoundElse = FoundElse;
1040e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    ConditionalStack.push_back(CI);
1050e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  }
1060e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  void pushConditionalLevel(const PPConditionalInfo &CI) {
1070e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    ConditionalStack.push_back(CI);
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1100e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  /// popConditionalLevel - Remove an entry off the top of the conditional
1110e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  /// stack, returning information about it.  If the conditional stack is empty,
1120e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  /// this returns true and does not fill in the arguments.
1130e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  bool popConditionalLevel(PPConditionalInfo &CI) {
114344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm    if (ConditionalStack.empty())
115344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm      return true;
116344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm    CI = ConditionalStack.pop_back_val();
1170e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    return false;
1180e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  }
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12080b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief Return the top of the conditional stack.
12180b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \pre This requires that there be a conditional active.
1220e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  PPConditionalInfo &peekConditionalLevel() {
1230e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    assert(!ConditionalStack.empty() && "No conditionals active!");
1240e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek    return ConditionalStack.back();
1250e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek  }
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
12863db2a78010f4d0f7a6783ea1e2d1469c9b154adTed Kremenek
12963db2a78010f4d0f7a6783ea1e2d1469c9b154adTed Kremenekpublic:
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
131eb41c28b78634ba2165b4aa04e33f3a12e590b0eTed Kremenek  //===--------------------------------------------------------------------===//
132eb41c28b78634ba2165b4aa04e33f3a12e590b0eTed Kremenek  // Misc. lexing methods.
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13480b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief After the preprocessor has parsed a \#include, lex and
13580b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// (potentially) macro expand the filename.
13680b5a2fea27561dce90c7588181185130d61e55eJames Dennett  ///
13780b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// If the sequence parsed is not lexically legal, emit a diagnostic and
13880b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// return a result EOD token.
139eb41c28b78634ba2165b4aa04e33f3a12e590b0eTed Kremenek  void LexIncludeFilename(Token &Result);
1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14180b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief Inform the lexer whether or not we are currently lexing a
14280b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// preprocessor directive.
14363db2a78010f4d0f7a6783ea1e2d1469c9b154adTed Kremenek  void setParsingPreprocessorDirective(bool f) {
14463db2a78010f4d0f7a6783ea1e2d1469c9b154adTed Kremenek    ParsingPreprocessorDirective = f;
14563db2a78010f4d0f7a6783ea1e2d1469c9b154adTed Kremenek  }
1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14780b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief Return true if this lexer is in raw mode or not.
14874d15dfd183b2082e8a5d4dfbf66bd861b220901Chris Lattner  bool isLexingRawMode() const { return LexingRawMode; }
14974d15dfd183b2082e8a5d4dfbf66bd861b220901Chris Lattner
15080b5a2fea27561dce90c7588181185130d61e55eJames Dennett  /// \brief Return the preprocessor object for this lexer.
15174d15dfd183b2082e8a5d4dfbf66bd861b220901Chris Lattner  Preprocessor *getPP() const { return PP; }
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  FileID getFileID() const {
15441938c8493b4380df738263166b746eacb33c309Ted Kremenek    assert(PP &&
15541938c8493b4380df738263166b746eacb33c309Ted Kremenek      "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
1562b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner    return FID;
15741938c8493b4380df738263166b746eacb33c309Ted Kremenek  }
1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
159d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis  /// \brief Number of SLocEntries before lexing the file.
160d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis  unsigned getInitialNumSLocEntries() const {
161d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis    return InitialNumSLocEntries;
162d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis  }
163d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis
1642b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
1652b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  /// getFileID(), this only works for lexers with attached preprocessors.
1662b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  const FileEntry *getFileEntry() const;
1676f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor
1686f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor  /// \brief Iterator that traverses the current stack of preprocessor
169809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// conditional directives (\#if/\#ifdef/\#ifndef).
170686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
1716f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor    conditional_iterator;
1726f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor
1736f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor  conditional_iterator conditional_begin() const {
1746f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor    return ConditionalStack.begin();
1756f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor  }
1766f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor  conditional_iterator conditional_end() const {
1776f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor    return ConditionalStack.end();
1786f2d1b111ed6d3c686303746e3949e3cbc9f3870Douglas Gregor  }
1790e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek};
1800e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek
1810e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek}  // end namespace clang
1820e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek
1830e977de1eacfbc143bdedad87c14b53814159023Ted Kremenek#endif
184