Skip to content

Commit 1e8ecb5

Browse files
committed
[clang][deps] Don't treat ObjC method args as module directives
`import:(type)name` is a method argument decl in ObjC, but the C++20 preprocessing rules say this is a preprocessing line. Because the dependency directive scanner is not language dependent, this patch extends the C++20 rule to exclude `module :` (which is never a valid module decl anyway), and `import :` that is not followed by an identifier. This is ok to do because in C++20 mode the compiler will later error on lines like this anyway, and the dependencies the scanner returns are still correct.
1 parent b1e03d3 commit 1e8ecb5

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

clang/lib/Lex/DependencyDirectivesScanner.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,18 @@ bool Scanner::lexModule(const char *&First, const char *const End) {
660660
// an import.
661661

662662
switch (*First) {
663-
case ':':
663+
case ':': {
664+
// `module :` is never the start of a valid module declaration.
665+
if (Id == "module") {
666+
skipLine(First, End);
667+
return false;
668+
}
669+
// `import:(type)name` is a valid ObjC method decl, so check one more token.
670+
(void)lexToken(First, End);
671+
if (!tryLexIdentifierOrSkipLine(First, End))
672+
return false;
673+
break;
674+
}
664675
case '<':
665676
case '"':
666677
break;

clang/unittests/Lex/DependencyDirectivesScannerTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,26 @@ ort \
970970
EXPECT_EQ(Directives[1].Kind, cxx_export_module_decl);
971971
}
972972

973+
TEST(MinimizeSourceToDependencyDirectivesTest, ObjCMethodArgs) {
974+
SmallVector<char, 128> Out;
975+
SmallVector<dependency_directives_scan::Token, 4> Tokens;
976+
SmallVector<Directive, 4> Directives;
977+
978+
StringRef Source = R"(
979+
@interface SomeObjcClass
980+
- (void)func:(int)otherData
981+
module:(int)module
982+
import:(int)import;
983+
@end
984+
)";
985+
986+
ASSERT_FALSE(
987+
minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
988+
// `module :` and `import :` not followed by an identifier are not treated as
989+
// directive lines because they can be method argument decls.
990+
EXPECT_EQ(Directives.size(), 2u); // 2 for the EOF tokens.
991+
}
992+
973993
TEST(MinimizeSourceToDependencyDirectivesTest, TokensBeforeEOF) {
974994
SmallString<128> Out;
975995

0 commit comments

Comments
 (0)