Skip to content

Commit 586b438

Browse files
committed
[clang][deps] Properly capture the global module and '\n' for all module directives
Previously, the newline after a module directive was not properly captured (or printed). According to P1857R3, each directive must, after skipping horizontal whitespace, be at the start of a logical line. Because the newline after module directives was missing, this invalidated the following line. This also fixes or removes tests that were in violation of P1857R3. This extends to Objective-C directives, which should also follow P1857R3. This also ensures that the global module fragment `module;` is captured by the dependency directives scanner.
1 parent 25553f7 commit 586b438

File tree

2 files changed

+26
-25
lines changed

2 files changed

+26
-25
lines changed

clang/lib/Lex/DependencyDirectivesScanner.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -560,15 +560,13 @@ bool Scanner::lexModuleDirectiveBody(DirectiveKind Kind, const char *&First,
560560
if (Tok.is(tok::semi))
561561
break;
562562
}
563+
564+
const auto &Tok = lexToken(First, End);
563565
pushDirective(Kind);
564-
skipWhitespace(First, End);
565-
if (First == End)
566+
if (Tok.is(tok::eof) || Tok.is(tok::eod))
566567
return false;
567-
if (!isVerticalWhitespace(*First))
568-
return reportError(
569-
DirectiveLoc, diag::err_dep_source_scanner_unexpected_tokens_at_import);
570-
skipNewline(First, End);
571-
return false;
568+
return reportError(DirectiveLoc,
569+
diag::err_dep_source_scanner_unexpected_tokens_at_import);
572570
}
573571

574572
dependency_directives_scan::Token &Scanner::lexToken(const char *&First,
@@ -905,14 +903,6 @@ bool Scanner::lexPPLine(const char *&First, const char *const End) {
905903
CurDirToks.clear();
906904
});
907905

908-
// Handle "@import".
909-
if (*First == '@')
910-
return lexAt(First, End);
911-
912-
// Handle module directives for C++20 modules.
913-
if (*First == 'i' || *First == 'e' || *First == 'm')
914-
return lexModule(First, End);
915-
916906
if (*First == '_') {
917907
if (isNextIdentifierOrSkipLine("_Pragma", First, End))
918908
return lex_Pragma(First, End);
@@ -925,6 +915,14 @@ bool Scanner::lexPPLine(const char *&First, const char *const End) {
925915
auto ScEx2 = make_scope_exit(
926916
[&]() { TheLexer.setParsingPreprocessorDirective(false); });
927917

918+
// Handle "@import".
919+
if (*First == '@')
920+
return lexAt(First, End);
921+
922+
// Handle module directives for C++20 modules.
923+
if (*First == 'i' || *First == 'e' || *First == 'm')
924+
return lexModule(First, End);
925+
928926
// Lex '#'.
929927
const dependency_directives_scan::Token &HashTok = lexToken(First, End);
930928
if (HashTok.is(tok::hashhash)) {

clang/unittests/Lex/DependencyDirectivesScannerTest.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -639,15 +639,12 @@ TEST(MinimizeSourceToDependencyDirectivesTest, AtImport) {
639639
ASSERT_FALSE(minimizeSourceToDependencyDirectives(" @ import A;\n", Out));
640640
EXPECT_STREQ("@import A;\n", Out.data());
641641

642-
ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A\n;", Out));
643-
EXPECT_STREQ("@import A;\n", Out.data());
644-
645642
ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A.B;\n", Out));
646643
EXPECT_STREQ("@import A.B;\n", Out.data());
647644

648645
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
649-
"@import /*x*/ A /*x*/ . /*x*/ B /*x*/ \n /*x*/ ; /*x*/", Out));
650-
EXPECT_STREQ("@import A.B;\n", Out.data());
646+
"@import /*x*/ A /*x*/ . /*x*/ B /*x*/ \\n /*x*/ ; /*x*/", Out));
647+
EXPECT_STREQ("@import A.B\\n;\n", Out.data());
651648
}
652649

653650
TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIncludesAndImports) {
@@ -1122,11 +1119,17 @@ ort \
11221119
)";
11231120
ASSERT_FALSE(
11241121
minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
1125-
EXPECT_STREQ("module\n;#include \"textual-header.h\"\nexport module m;"
1126-
"exp\\\nort import:l[[rename]];"
1127-
"import<<=3;import a b d e d e f e;"
1128-
"import foo[[no_unique_address]];import foo();"
1129-
"import f(:sefse);import f(->a=3);"
1122+
1123+
EXPECT_STREQ("module;\n"
1124+
"#include \"textual-header.h\"\n"
1125+
"export module m;\n"
1126+
"exp\\\nort import:l[[rename]];\n"
1127+
"import<<=3;\n"
1128+
"import a b d e d e f e;\n"
1129+
"import foo[[no_unique_address]];\n"
1130+
"import foo();\n"
1131+
"import f(:sefse);\n"
1132+
"import f(->a=3);\n"
11301133
"<TokBeforeEOF>\n",
11311134
Out.data());
11321135
ASSERT_EQ(Directives.size(), 12u);

0 commit comments

Comments
 (0)