]> granicus.if.org Git - clang/commitdiff
Modules: Teach the preprocessor to recognize 'import' only after an '@'.
authorDouglas Gregor <dgregor@apple.com>
Thu, 7 Nov 2013 22:55:02 +0000 (22:55 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 7 Nov 2013 22:55:02 +0000 (22:55 +0000)
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 <rdar://problem/15084587>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194225 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/Preprocessor.h
lib/Lex/Preprocessor.cpp
test/Modules/import-decl.cpp

index adfc6f1951b66deba73b226a742fa8aae8b7e6e2..223fd470eca1d7d2bb88b8c027d118ea4e5c2bbb 100644 (file)
@@ -222,7 +222,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
 
   /// \brief The module import path that we're currently processing.
   SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 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;
index 81e6f364cfbe8c66684d663451921711f70aedf1..b500efee4e6186094304ce501eba2058074652cb 100644 (file)
@@ -65,6 +65,7 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> 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);
 }
 
 
index 900e090c0c5fae5fe06868fd76eff4ba3c125e22..56428b3eba65faebc7da9815c6585b2fd36968e7 100644 (file)
@@ -8,3 +8,12 @@
 int main() {
   return 0;
 }
+
+// <rdar://problem/15084587>
+@interface A
+-method;
+@end
+
+void testImport(A *import) {
+  [import method];
+}