diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-09-07 23:11:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-09-07 23:11:54 +0000 |
commit | b8db7cd9ac05c522855631670ec2e97255384f5a (patch) | |
tree | 219ea0bfbdfdca93fcff2d45221abc0ffb660eac /include/clang | |
parent | 0e2ca014bdf92b405f7c02f2d37532f4c9b9b663 (diff) |
Optimize the preprocessor's handling of the __import_module__
keyword. We now handle this keyword in HandleIdentifier, making a note
for ourselves when we've seen the __import_module__ keyword so that
the next lexed token can trigger a module import (if needed). This
greatly simplifies Preprocessor::Lex(), and completely erases the 5.5%
-Eonly slowdown Argiris noted when I originally implemented
__import_module__. Big thanks to Argiris for noting that horrible
regression!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139265 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/Basic/IdentifierTable.h | 2 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 56 |
2 files changed, 32 insertions, 26 deletions
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index bd0b539d20..97cd68ee55 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -252,7 +252,7 @@ private: void RecomputeNeedsHandleIdentifier() { NeedsHandleIdentifier = (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | - isExtensionToken()); + isExtensionToken() || (getTokenID() == tok::kw___import_module__)); } }; diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 47af19e496..c404149f18 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -119,9 +119,6 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// \brief Whether we have already loaded macros from the external source. mutable bool ReadMacrosFromExternalSource : 1; - /// \brief Tracks the depth of Lex() Calls. - unsigned LexDepth; - /// Identifiers - This is mapping/lookup information for all identifiers in /// the program, including program keywords. mutable IdentifierTable Identifiers; @@ -164,6 +161,10 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// for preprocessing. SourceLocation CodeCompletionFileLoc; + /// \brief The source location of the __import_module__ keyword we just + /// lexed, if any. + SourceLocation ModuleImportLoc; + /// \brief True if we hit the code-completion point. bool CodeCompletionReached; @@ -187,7 +188,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// if not expanding a macro. This is an alias for either CurLexer or /// CurPTHLexer. PreprocessorLexer *CurPPLexer; - + /// CurLookup - The DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. This allows us to /// implement #include_next and find directory-specific properties. @@ -197,20 +198,31 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// expanding a macro. One of CurLexer and CurTokenLexer must be null. llvm::OwningPtr<TokenLexer> CurTokenLexer; + /// \brief The kind of lexer we're currently working with. + enum CurLexerKind { + CLK_Lexer, + CLK_PTHLexer, + CLK_TokenLexer, + CLK_CachingLexer, + CLK_LexAfterModuleImport + } CurLexerKind; + /// IncludeMacroStack - This keeps track of the stack of files currently /// #included, and macros currently being expanded from, not counting /// CurLexer/CurTokenLexer. struct IncludeStackInfo { + enum CurLexerKind CurLexerKind; Lexer *TheLexer; PTHLexer *ThePTHLexer; PreprocessorLexer *ThePPLexer; TokenLexer *TheTokenLexer; const DirectoryLookup *TheDirLookup; - IncludeStackInfo(Lexer *L, PTHLexer* P, PreprocessorLexer* PPL, + IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P, + PreprocessorLexer* PPL, TokenLexer* TL, const DirectoryLookup *D) - : TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL), TheTokenLexer(TL), - TheDirLookup(D) {} + : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL), + TheTokenLexer(TL), TheDirLookup(D) {} }; std::vector<IncludeStackInfo> IncludeMacroStack; @@ -555,22 +567,17 @@ public: /// Lex - To lex a token from the preprocessor, just pull a token from the /// current lexer or macro object. void Lex(Token &Result) { - ++LexDepth; - if (CurLexer) - CurLexer->Lex(Result); - else if (CurPTHLexer) - CurPTHLexer->Lex(Result); - else if (CurTokenLexer) - CurTokenLexer->Lex(Result); - else - CachingLex(Result); - --LexDepth; - - // If we have the __import_module__ keyword, handle the module import now. - if (Result.getKind() == tok::kw___import_module__ && LexDepth == 0) - HandleModuleImport(Result); + switch (CurLexerKind) { + case CLK_Lexer: CurLexer->Lex(Result); break; + case CLK_PTHLexer: CurPTHLexer->Lex(Result); break; + case CLK_TokenLexer: CurTokenLexer->Lex(Result); break; + case CLK_CachingLexer: CachingLex(Result); break; + case CLK_LexAfterModuleImport: LexAfterModuleImport(Result); break; + } } + void LexAfterModuleImport(Token &Result); + /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get /// something not a comment. This is useful in -E -C mode where comments /// would foul up preprocessor directive handling. @@ -997,7 +1004,8 @@ public: private: void PushIncludeMacroStack() { - IncludeMacroStack.push_back(IncludeStackInfo(CurLexer.take(), + IncludeMacroStack.push_back(IncludeStackInfo(CurLexerKind, + CurLexer.take(), CurPTHLexer.take(), CurPPLexer, CurTokenLexer.take(), @@ -1011,6 +1019,7 @@ private: CurPPLexer = IncludeMacroStack.back().ThePPLexer; CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer); CurDirLookup = IncludeMacroStack.back().TheDirLookup; + CurLexerKind = IncludeMacroStack.back().CurLexerKind; IncludeMacroStack.pop_back(); } @@ -1065,9 +1074,6 @@ private: /// the macro should not be expanded return true, otherwise return false. bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI); - /// \brief Handle a module import directive. - void HandleModuleImport(Token &Import); - /// \brief Cache macro expanded tokens for TokenLexers. // /// Works like a stack; a TokenLexer adds the macro expanded tokens that is |