summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-11-07 22:55:02 +0000
committerDouglas Gregor <dgregor@apple.com>2013-11-07 22:55:02 +0000
commit594b8c934f79de7c2085a6ca7fb519648a7ff684 (patch)
treefc076913310c4493f343f3825e14b24206cee7ff
parent4b60a1594d2c6b1d18b0839614cd414306ca0176 (diff)
downloadbcm5719-llvm-594b8c934f79de7c2085a6ca7fb519648a7ff684.tar.gz
bcm5719-llvm-594b8c934f79de7c2085a6ca7fb519648a7ff684.zip
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 <rdar://problem/15084587>. llvm-svn: 194225
-rw-r--r--clang/include/clang/Lex/Preprocessor.h5
-rw-r--r--clang/lib/Lex/Preprocessor.cpp10
-rw-r--r--clang/test/Modules/import-decl.cpp9
3 files changed, 20 insertions, 4 deletions
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index adfc6f1951b..223fd470eca 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -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;
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 81e6f364cfb..b500efee4e6 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -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);
}
diff --git a/clang/test/Modules/import-decl.cpp b/clang/test/Modules/import-decl.cpp
index 900e090c0c5..56428b3eba6 100644
--- a/clang/test/Modules/import-decl.cpp
+++ b/clang/test/Modules/import-decl.cpp
@@ -8,3 +8,12 @@
int main() {
return 0;
}
+
+// <rdar://problem/15084587>
+@interface A
+-method;
+@end
+
+void testImport(A *import) {
+ [import method];
+}
OpenPOWER on IntegriCloud