Skip to content

Commit 4272847

Browse files
authored
[clang][deps] Don't treat ObjC method args as module directives (#97654)
`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 af5352f commit 4272847

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,23 @@ ort \
970970
EXPECT_EQ(Directives[1].Kind, cxx_export_module_decl);
971971
}
972972

973+
TEST(MinimizeSourceToDependencyDirectivesTest, ObjCMethodArgs) {
974+
SmallVector<char, 128> Out;
975+
976+
StringRef Source = R"(
977+
@interface SomeObjcClass
978+
- (void)func:(int)otherData
979+
module:(int)module
980+
import:(int)import;
981+
@end
982+
)";
983+
984+
ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
985+
// `module :` and `import :` not followed by an identifier are not treated as
986+
// directive lines because they can be method argument decls.
987+
EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
988+
}
989+
973990
TEST(MinimizeSourceToDependencyDirectivesTest, TokensBeforeEOF) {
974991
SmallString<128> Out;
975992

0 commit comments

Comments
 (0)