diff options
Diffstat (limited to 'include/clang/Lex/MultipleIncludeOpt.h')
-rw-r--r-- | include/clang/Lex/MultipleIncludeOpt.h | 181 |
1 files changed, 0 insertions, 181 deletions
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h deleted file mode 100644 index 83e6f99..0000000 --- a/include/clang/Lex/MultipleIncludeOpt.h +++ /dev/null @@ -1,181 +0,0 @@ -//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the MultipleIncludeOpt interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H -#define LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H - -#include "clang/Basic/SourceLocation.h" - -namespace clang { -class IdentifierInfo; - -/// \brief Implements the simple state machine that the Lexer class uses to -/// detect files subject to the 'multiple-include' optimization. -/// -/// The public methods in this class are triggered by various -/// events that occur when a file is lexed, and after the entire file is lexed, -/// information about which macro (if any) controls the header is returned. -class MultipleIncludeOpt { - /// ReadAnyTokens - This is set to false when a file is first opened and true - /// any time a token is returned to the client or a (non-multiple-include) - /// directive is parsed. When the final \#endif is parsed this is reset back - /// to false, that way any tokens before the first \#ifdef or after the last - /// \#endif can be easily detected. - bool ReadAnyTokens; - - /// ImmediatelyAfterTopLevelIfndef - This is true when the only tokens - /// processed in the file so far is an #ifndef and an identifier. Used in - /// the detection of header guards in a file. - bool ImmediatelyAfterTopLevelIfndef; - - /// ReadAnyTokens - This is set to false when a file is first opened and true - /// any time a token is returned to the client or a (non-multiple-include) - /// directive is parsed. When the final #endif is parsed this is reset back - /// to false, that way any tokens before the first #ifdef or after the last - /// #endif can be easily detected. - bool DidMacroExpansion; - - /// TheMacro - The controlling macro for a file, if valid. - /// - const IdentifierInfo *TheMacro; - - /// DefinedMacro - The macro defined right after TheMacro, if any. - const IdentifierInfo *DefinedMacro; - - SourceLocation MacroLoc; - SourceLocation DefinedLoc; -public: - MultipleIncludeOpt() { - ReadAnyTokens = false; - ImmediatelyAfterTopLevelIfndef = false; - DidMacroExpansion = false; - TheMacro = nullptr; - DefinedMacro = nullptr; - } - - SourceLocation GetMacroLocation() const { - return MacroLoc; - } - - SourceLocation GetDefinedLocation() const { - return DefinedLoc; - } - - void resetImmediatelyAfterTopLevelIfndef() { - ImmediatelyAfterTopLevelIfndef = false; - } - - void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc) { - DefinedMacro = M; - DefinedLoc = Loc; - } - - /// Invalidate - Permanently mark this file as not being suitable for the - /// include-file optimization. - void Invalidate() { - // If we have read tokens but have no controlling macro, the state-machine - // below can never "accept". - ReadAnyTokens = true; - ImmediatelyAfterTopLevelIfndef = false; - DefinedMacro = nullptr; - TheMacro = nullptr; - } - - /// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the - /// top of the file when reading preprocessor directives. Otherwise, reading - /// the "ifndef x" would count as reading tokens. - bool getHasReadAnyTokensVal() const { return ReadAnyTokens; } - - /// getImmediatelyAfterTopLevelIfndef - returns true if the last directive - /// was an #ifndef at the beginning of the file. - bool getImmediatelyAfterTopLevelIfndef() const { - return ImmediatelyAfterTopLevelIfndef; - } - - // If a token is read, remember that we have seen a side-effect in this file. - void ReadToken() { - ReadAnyTokens = true; - ImmediatelyAfterTopLevelIfndef = false; - } - - /// ExpandedMacro - When a macro is expanded with this lexer as the current - /// buffer, this method is called to disable the MIOpt if needed. - void ExpandedMacro() { DidMacroExpansion = true; } - - /// \brief Called when entering a top-level \#ifndef directive (or the - /// "\#if !defined" equivalent) without any preceding tokens. - /// - /// Note, we don't care about the input value of 'ReadAnyTokens'. The caller - /// ensures that this is only called if there are no tokens read before the - /// \#ifndef. The caller is required to do this, because reading the \#if - /// line obviously reads in in tokens. - void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc) { - // If the macro is already set, this is after the top-level #endif. - if (TheMacro) - return Invalidate(); - - // If we have already expanded a macro by the end of the #ifndef line, then - // there is a macro expansion *in* the #ifndef line. This means that the - // condition could evaluate differently when subsequently #included. Reject - // this. - if (DidMacroExpansion) - return Invalidate(); - - // Remember that we're in the #if and that we have the macro. - ReadAnyTokens = true; - ImmediatelyAfterTopLevelIfndef = true; - TheMacro = M; - MacroLoc = Loc; - } - - /// \brief Invoked when a top level conditional (except \#ifndef) is found. - void EnterTopLevelConditional() { - // If a conditional directive (except #ifndef) is found at the top level, - // there is a chunk of the file not guarded by the controlling macro. - Invalidate(); - } - - /// \brief Called when the lexer exits the top-level conditional. - void ExitTopLevelConditional() { - // If we have a macro, that means the top of the file was ok. Set our state - // back to "not having read any tokens" so we can detect anything after the - // #endif. - if (!TheMacro) return Invalidate(); - - // At this point, we haven't "read any tokens" but we do have a controlling - // macro. - ReadAnyTokens = false; - ImmediatelyAfterTopLevelIfndef = false; - } - - /// \brief Once the entire file has been lexed, if there is a controlling - /// macro, return it. - const IdentifierInfo *GetControllingMacroAtEndOfFile() const { - // If we haven't read any tokens after the #endif, return the controlling - // macro if it's valid (if it isn't, it will be null). - if (!ReadAnyTokens) - return TheMacro; - return nullptr; - } - - /// \brief If the ControllingMacro is followed by a macro definition, return - /// the macro that was defined. - const IdentifierInfo *GetDefinedMacro() const { - return DefinedMacro; - } -}; - -} // end namespace clang - -#endif |