[cfe-commits] r139265 - in /cfe/trunk: include/clang/Basic/IdentifierTable.h include/clang/Lex/Preprocessor.h lib/Lex/PPCaching.cpp lib/Lex/PPLexerChange.cpp lib/Lex/Preprocessor.cpp
Douglas Gregor
dgregor at apple.com
Wed Sep 7 16:11:55 PDT 2011
Author: dgregor
Date: Wed Sep 7 18:11:54 2011
New Revision: 139265
URL: http://llvm.org/viewvc/llvm-project?rev=139265&view=rev
Log:
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!
Modified:
cfe/trunk/include/clang/Basic/IdentifierTable.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Lex/PPCaching.cpp
cfe/trunk/lib/Lex/PPLexerChange.cpp
cfe/trunk/lib/Lex/Preprocessor.cpp
Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=139265&r1=139264&r2=139265&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Wed Sep 7 18:11:54 2011
@@ -252,7 +252,7 @@
void RecomputeNeedsHandleIdentifier() {
NeedsHandleIdentifier =
(isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
- isExtensionToken());
+ isExtensionToken() || (getTokenID() == tok::kw___import_module__));
}
};
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=139265&r1=139264&r2=139265&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Wed Sep 7 18:11:54 2011
@@ -119,9 +119,6 @@
/// \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 @@
/// 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 @@
/// 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 @@
/// 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 @@
/// 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 @@
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 @@
CurPPLexer = IncludeMacroStack.back().ThePPLexer;
CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer);
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
+ CurLexerKind = IncludeMacroStack.back().CurLexerKind;
IncludeMacroStack.pop_back();
}
@@ -1065,9 +1074,6 @@
/// 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
Modified: cfe/trunk/lib/Lex/PPCaching.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPCaching.cpp?rev=139265&r1=139264&r2=139265&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPCaching.cpp (original)
+++ cfe/trunk/lib/Lex/PPCaching.cpp Wed Sep 7 18:11:54 2011
@@ -74,6 +74,8 @@
return;
PushIncludeMacroStack();
+ if (CurLexerKind != CLK_LexAfterModuleImport)
+ CurLexerKind = CLK_CachingLexer;
}
Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=139265&r1=139264&r2=139265&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)
+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Wed Sep 7 18:11:54 2011
@@ -113,7 +113,9 @@
CurLexer.reset(TheLexer);
CurPPLexer = TheLexer;
CurDirLookup = CurDir;
-
+ if (CurLexerKind != CLK_LexAfterModuleImport)
+ CurLexerKind = CLK_Lexer;
+
// Notify the client, if desired, that we are in a new source file.
if (Callbacks && !CurLexer->Is_PragmaLexer) {
SrcMgr::CharacteristicKind FileType =
@@ -135,7 +137,9 @@
CurDirLookup = CurDir;
CurPTHLexer.reset(PL);
CurPPLexer = CurPTHLexer.get();
-
+ if (CurLexerKind != CLK_LexAfterModuleImport)
+ CurLexerKind = CLK_PTHLexer;
+
// Notify the client, if desired, that we are in a new source file.
if (Callbacks) {
FileID FID = CurPPLexer->getFileID();
@@ -159,6 +163,8 @@
CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]);
CurTokenLexer->Init(Tok, ILEnd, Args);
}
+ if (CurLexerKind != CLK_LexAfterModuleImport)
+ CurLexerKind = CLK_TokenLexer;
}
/// EnterTokenStream - Add a "macro" context to the top of the include stack,
@@ -188,6 +194,8 @@
CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]);
CurTokenLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
}
+ if (CurLexerKind != CLK_LexAfterModuleImport)
+ CurLexerKind = CLK_TokenLexer;
}
/// HandleEndOfFile - This callback is invoked when the lexer hits the end of
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=139265&r1=139264&r2=139265&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Wed Sep 7 18:11:54 2011
@@ -144,8 +144,6 @@
// We haven't read anything from the external source.
ReadMacrosFromExternalSource = false;
- LexDepth = 0;
-
// "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
// This gets unpoisoned where it is allowed.
(Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
@@ -524,27 +522,44 @@
// like "#define TY typeof", "TY(1) x".
if (II.isExtensionToken() && !DisableMacroExpansion)
Diag(Identifier, diag::ext_token_used);
+
+ // If this is the '__import_module__' keyword, note that the next token
+ // indicates a module name.
+ if (II.getTokenID() == tok::kw___import_module__ &&
+ !InMacroArgs && !DisableMacroExpansion) {
+ ModuleImportLoc = Identifier.getLocation();
+ CurLexerKind = CLK_LexAfterModuleImport;
+ }
}
-void Preprocessor::HandleModuleImport(Token &Import) {
+/// \brief Lex a token following the __import_module__ keyword.
+void Preprocessor::LexAfterModuleImport(Token &Result) {
+ // Figure out what kind of lexer we actually have.
+ if (CurLexer)
+ CurLexerKind = CLK_Lexer;
+ else if (CurPTHLexer)
+ CurLexerKind = CLK_PTHLexer;
+ else if (CurTokenLexer)
+ CurLexerKind = CLK_TokenLexer;
+ else
+ CurLexerKind = CLK_CachingLexer;
+
+ // Lex the next token.
+ Lex(Result);
+
// The token sequence
//
// __import_module__ identifier
//
- // indicates a module import directive. We load the module and then
- // leave the token sequence for the parser.
- Token ModuleNameTok = LookAhead(0);
- if (ModuleNameTok.getKind() != tok::identifier)
+ // indicates a module import directive. We already saw the __import_module__
+ // keyword, so now we're looking for the identifier.
+ if (Result.getKind() != tok::identifier)
return;
- (void)TheModuleLoader.loadModule(Import.getLocation(),
- *ModuleNameTok.getIdentifierInfo(),
- ModuleNameTok.getLocation());
-
- // FIXME: Transmogrify __import_module__ into some kind of AST-only
- // __import_module__ that is not recognized by the preprocessor but is
- // recognized by the parser. It would also be useful to stash the ModuleKey
- // somewhere, so we don't try to load the module twice.
+ // Load the module.
+ (void)TheModuleLoader.loadModule(ModuleImportLoc,
+ *Result.getIdentifierInfo(),
+ Result.getLocation());
}
void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
More information about the cfe-commits
mailing list