Take an entirely different approach to handling the "parsing" of

__import__ within the preprocessor, since the prior one foolishly
assumed that Preprocessor::Lex() was re-entrant. We now handle
__import__ at the top level (only), after macro expansion. This should
fix the buildbot failures.

llvm-svn: 138704
This commit is contained in:
Douglas Gregor 2011-08-27 06:37:51 +00:00
parent d22f9b395b
commit d90c3c92d5
4 changed files with 13 additions and 9 deletions

View File

@ -252,7 +252,7 @@ private:
void RecomputeNeedsHandleIdentifier() { void RecomputeNeedsHandleIdentifier() {
NeedsHandleIdentifier = NeedsHandleIdentifier =
(isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
isExtensionToken() | (getTokenID() == tok::kw___import__)); isExtensionToken());
} }
}; };

View File

@ -118,6 +118,9 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// \brief Whether we have already loaded macros from the external source. /// \brief Whether we have already loaded macros from the external source.
mutable bool ReadMacrosFromExternalSource : 1; mutable bool ReadMacrosFromExternalSource : 1;
/// \brief Tracks the depth of Lex() Calls.
unsigned LexDepth;
/// Identifiers - This is mapping/lookup information for all identifiers in /// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords. /// the program, including program keywords.
mutable IdentifierTable Identifiers; mutable IdentifierTable Identifiers;
@ -531,6 +534,7 @@ public:
/// Lex - To lex a token from the preprocessor, just pull a token from the /// Lex - To lex a token from the preprocessor, just pull a token from the
/// current lexer or macro object. /// current lexer or macro object.
void Lex(Token &Result) { void Lex(Token &Result) {
++LexDepth;
if (CurLexer) if (CurLexer)
CurLexer->Lex(Result); CurLexer->Lex(Result);
else if (CurPTHLexer) else if (CurPTHLexer)
@ -539,6 +543,11 @@ public:
CurTokenLexer->Lex(Result); CurTokenLexer->Lex(Result);
else else
CachingLex(Result); CachingLex(Result);
--LexDepth;
// If we have the __import__ keyword, handle the module import now.
if (Result.getKind() == tok::kw___import__ && LexDepth == 0)
HandleModuleImport(Result);
} }
/// LexNonComment - Lex a token. If it's a comment, keep lexing until we get /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get

View File

@ -88,6 +88,8 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
// We haven't read anything from the external source. // We haven't read anything from the external source.
ReadMacrosFromExternalSource = false; ReadMacrosFromExternalSource = false;
LexDepth = 0;
// "Poison" __VA_ARGS__, which can only appear in the expansion of a macro. // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
// This gets unpoisoned where it is allowed. // This gets unpoisoned where it is allowed.
(Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned(); (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
@ -484,7 +486,7 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) { if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) {
if (MI->isEnabled()) { if (MI->isEnabled()) {
if (!HandleMacroExpandedIdentifier(Identifier, MI)) if (!HandleMacroExpandedIdentifier(Identifier, MI))
goto finish; return;
} else { } else {
// C99 6.10.3.4p2 says that a disabled macro may never again be // 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 // expanded, even if it's in a context where it could be expanded in the
@ -506,12 +508,6 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
// like "#define TY typeof", "TY(1) x". // like "#define TY typeof", "TY(1) x".
if (II.isExtensionToken() && !DisableMacroExpansion) if (II.isExtensionToken() && !DisableMacroExpansion)
Diag(Identifier, diag::ext_token_used); Diag(Identifier, diag::ext_token_used);
finish:
// If we have the start of a module import, handle it now.
if (Identifier.is(tok::kw___import__) &&
!InMacroArgs && !DisableMacroExpansion)
HandleModuleImport(Identifier);
} }
void Preprocessor::HandleModuleImport(Token &Import) { void Preprocessor::HandleModuleImport(Token &Import) {

View File

@ -18,7 +18,6 @@ void test(int i, float f) {
// RUN: %clang_cc1 -emit-module -x c++ -o %T/lookup_right_cxx.pcm %S/Inputs/lookup_right.hpp // RUN: %clang_cc1 -emit-module -x c++ -o %T/lookup_right_cxx.pcm %S/Inputs/lookup_right.hpp
// RUN: %clang_cc1 -x c++ -I %T %s -verify // RUN: %clang_cc1 -x c++ -I %T %s -verify
// RUN: %clang_cc1 -ast-print -x c++ -I %T %s | FileCheck -check-prefix=CHECK-PRINT %s // RUN: %clang_cc1 -ast-print -x c++ -I %T %s | FileCheck -check-prefix=CHECK-PRINT %s
// XFAIL: win32
// CHECK-PRINT: int *f0(int *); // CHECK-PRINT: int *f0(int *);
// CHECK-PRINT: float *f0(float *); // CHECK-PRINT: float *f0(float *);