From a5ba7b405dff48a5a0a63fff32c99eedb044842b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 7 Nov 2013 22:55:02 +0000 Subject: [PATCH] Modules: Teach the preprocessor to recognize 'import' only after an '@'. The preprocessor currently recognizes module declarations to load a module based on seeing the 'import' keyword followed by an identifier. This sequence is fairly unlikely in C (one would need a type named 'import'), but is more common in Objective-C (where a variable named 'import' can cause problems). Since import declarations currently require a leading '@', recognize that in the preprocessor as well. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194225 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/Preprocessor.h | 5 ++++- lib/Lex/Preprocessor.cpp | 10 +++++++--- test/Modules/import-decl.cpp | 9 +++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index adfc6f1951..223fd470ec 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -222,7 +222,10 @@ class Preprocessor : public RefCountedBase { /// \brief The module import path that we're currently processing. SmallVector, 2> ModuleImportPath; - + + /// \brief Whether the last token we lexed was an '@'. + bool LastTokenWasAt; + /// \brief Whether the module import expectes an identifier next. Otherwise, /// it expects a '.' or ';'. bool ModuleImportExpectsIdentifier; diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 81e6f364cf..b500efee4e 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -65,6 +65,7 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr PPOpts, TheModuleLoader(TheModuleLoader), ExternalSource(0), Identifiers(opts, IILookup), IncrementalProcessing(IncrProcessing), CodeComplete(0), CodeCompletionFile(0), CodeCompletionOffset(0), + LastTokenWasAt(false), ModuleImportExpectsIdentifier(false), CodeCompletionReached(0), SkipMainFilePreamble(0, true), CurPPLexer(0), CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0), MICache(0), @@ -687,14 +688,15 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { if (II.isExtensionToken() && !DisableMacroExpansion) Diag(Identifier, diag::ext_token_used); - // If this is the 'import' contextual keyword, note + // If this is the 'import' contextual keyword following an '@', note // that the next token indicates a module name. // // Note that we do not treat 'import' as a contextual // keyword when we're in a caching lexer, because caching lexers only get // used in contexts where import declarations are disallowed. - if (II.isModulesImport() && !InMacroArgs && !DisableMacroExpansion && - getLangOpts().Modules && CurLexerKind != CLK_CachingLexer) { + if (LastTokenWasAt && II.isModulesImport() && !InMacroArgs && + !DisableMacroExpansion && getLangOpts().Modules && + CurLexerKind != CLK_CachingLexer) { ModuleImportLoc = Identifier.getLocation(); ModuleImportPath.clear(); ModuleImportExpectsIdentifier = true; @@ -727,6 +729,8 @@ void Preprocessor::Lex(Token &Result) { break; } } while (!ReturnedToken); + + LastTokenWasAt = Result.is(tok::at); } diff --git a/test/Modules/import-decl.cpp b/test/Modules/import-decl.cpp index 900e090c0c..56428b3eba 100644 --- a/test/Modules/import-decl.cpp +++ b/test/Modules/import-decl.cpp @@ -8,3 +8,12 @@ int main() { return 0; } + +// +@interface A +-method; +@end + +void testImport(A *import) { + [import method]; +} -- 2.40.0