diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2013-09-19 00:41:32 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2013-09-19 00:41:32 +0000 |
commit | 0834a4b90139341eacdfff167b052595a95cf2e5 (patch) | |
tree | faeeee0d2c1fa35cfaf80c16b4e4ff862e749a85 /clang/lib/Lex/Preprocessor.cpp | |
parent | 5cc15addbec0797e8c8e2b8dc099415762b4b8de (diff) | |
download | bcm5719-llvm-0834a4b90139341eacdfff167b052595a95cf2e5.tar.gz bcm5719-llvm-0834a4b90139341eacdfff167b052595a95cf2e5.zip |
Make Preprocessor::Lex non-recursive.
Before this patch, Lex() would recurse whenever the current lexer changed (e.g.
upon entry into a macro). This patch turns the recursion into a loop: the
various lex routines now don't return a token when the current lexer changes,
and at the top level Preprocessor::Lex() now loops until it finds a token.
Normally, the recursion wouldn't end up being very deep, but the recursion depth
can explode in edge cases like a bunch of consecutive macros which expand to
nothing (like in the testcase test/Preprocessor/macro_expand_empty.c in this
patch).
<rdar://problem/14569770>
llvm-svn: 190980
Diffstat (limited to 'clang/lib/Lex/Preprocessor.cpp')
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 035f751d0d2..81e6f364cfb 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -614,7 +614,7 @@ void Preprocessor::HandlePoisonedIdentifier(Token & Identifier) { /// IdentifierInfo's 'isHandleIdentifierCase' bit. If this method changes, the /// IdentifierInfo methods that compute these properties will need to change to /// match. -void Preprocessor::HandleIdentifier(Token &Identifier) { +bool Preprocessor::HandleIdentifier(Token &Identifier) { assert(Identifier.getIdentifierInfo() && "Can't handle identifiers without identifier info!"); @@ -648,8 +648,10 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { MacroInfo *MI = MD->getMacroInfo(); if (!DisableMacroExpansion) { if (!Identifier.isExpandDisabled() && MI->isEnabled()) { - if (!HandleMacroExpandedIdentifier(Identifier, MD)) - return; + // C99 6.10.3p10: If the preprocessing token immediately after the + // macro name isn't a '(', this macro should not be expanded. + if (!MI->isFunctionLike() || isNextPPTokenLParen()) + return HandleMacroExpandedIdentifier(Identifier, MD); } else { // C99 6.10.3.4p2 says that a disabled macro may never again be // expanded, even if it's in a context where it could be expanded in the @@ -698,8 +700,36 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { ModuleImportExpectsIdentifier = true; CurLexerKind = CLK_LexAfterModuleImport; } + return true; } +void Preprocessor::Lex(Token &Result) { + // We loop here until a lex function retuns a token; this avoids recursion. + bool ReturnedToken; + do { + switch (CurLexerKind) { + case CLK_Lexer: + ReturnedToken = CurLexer->Lex(Result); + break; + case CLK_PTHLexer: + ReturnedToken = CurPTHLexer->Lex(Result); + break; + case CLK_TokenLexer: + ReturnedToken = CurTokenLexer->Lex(Result); + break; + case CLK_CachingLexer: + CachingLex(Result); + ReturnedToken = true; + break; + case CLK_LexAfterModuleImport: + LexAfterModuleImport(Result); + ReturnedToken = true; + break; + } + } while (!ReturnedToken); +} + + /// \brief Lex a token following the 'import' contextual keyword. /// void Preprocessor::LexAfterModuleImport(Token &Result) { |