Skip to content

Commit 15d5f5d

Browse files
committed
[clang-scan-deps] Allow continuation line backslashes followed by whitespace
in the dependency source minimizer Clang allows continuations that have whitespace between the backslash and the newline. This patch ensures that the dependency source minimizer can handle the whitespace between the backslash and the newline when looking for a line continuation. Differential Revision: https://reviews.llvm.org/D68052 llvm-svn: 373007
1 parent f1a5a93 commit 15d5f5d

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

clang/lib/Lex/DependencyDirectivesSourceMinimizer.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,20 @@ static void skipToNewlineRaw(const char *&First, const char *const End) {
244244
}
245245
}
246246

247-
static const char *reverseOverSpaces(const char *First, const char *Last) {
247+
static const char *findLastNonSpace(const char *First, const char *Last) {
248248
assert(First <= Last);
249-
const char *PrevLast = Last;
250-
while (First != Last && isHorizontalWhitespace(Last[-1])) {
251-
PrevLast = Last;
249+
while (First != Last && isHorizontalWhitespace(Last[-1]))
252250
--Last;
253-
}
254-
return PrevLast;
251+
return Last;
252+
}
253+
254+
static const char *findFirstTrailingSpace(const char *First,
255+
const char *Last) {
256+
const char *LastNonSpace = findLastNonSpace(First, Last);
257+
if (Last == LastNonSpace)
258+
return Last;
259+
assert(isHorizontalWhitespace(LastNonSpace[0]));
260+
return LastNonSpace + 1;
255261
}
256262

257263
static void skipLineComment(const char *&First, const char *const End) {
@@ -385,7 +391,7 @@ void Minimizer::printToNewline(const char *&First, const char *const End) {
385391
}
386392

387393
// Deal with "//..." and "/*...*/".
388-
append(First, reverseOverSpaces(First, Last));
394+
append(First, findFirstTrailingSpace(First, Last));
389395
First = Last;
390396

391397
if (Last[1] == '/') {
@@ -400,15 +406,20 @@ void Minimizer::printToNewline(const char *&First, const char *const End) {
400406
} while (Last != End && !isVerticalWhitespace(*Last));
401407

402408
// Print out the string.
403-
if (Last == End || Last == First || Last[-1] != '\\') {
404-
append(First, reverseOverSpaces(First, Last));
409+
const char *LastBeforeTrailingSpace = findLastNonSpace(First, Last);
410+
if (Last == End || LastBeforeTrailingSpace == First ||
411+
LastBeforeTrailingSpace[-1] != '\\') {
412+
append(First, LastBeforeTrailingSpace);
405413
First = Last;
406414
skipNewline(First, End);
407415
return;
408416
}
409417

410-
// Print up to the backslash, backing up over spaces.
411-
append(First, reverseOverSpaces(First, Last - 1));
418+
// Print up to the backslash, backing up over spaces. Preserve at least one
419+
// space, as the space matters when tokens are separated by a line
420+
// continuation.
421+
append(First, findFirstTrailingSpace(
422+
First, LastBeforeTrailingSpace - 1));
412423

413424
First = Last;
414425
skipNewline(First, End);

clang/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,19 @@ TEST(MinimizeSourceToDependencyDirectivesTest, DefineHorizontalWhitespace) {
157157

158158
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
159159
"#define MACRO(\t)\tcon \t tent\t", Out));
160-
EXPECT_STREQ("#define MACRO() con \t tent\t\n", Out.data());
160+
EXPECT_STREQ("#define MACRO() con \t tent\n", Out.data());
161161

162162
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
163163
"#define MACRO(\f)\fcon \f tent\f", Out));
164-
EXPECT_STREQ("#define MACRO() con \f tent\f\n", Out.data());
164+
EXPECT_STREQ("#define MACRO() con \f tent\n", Out.data());
165165

166166
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
167167
"#define MACRO(\v)\vcon \v tent\v", Out));
168-
EXPECT_STREQ("#define MACRO() con \v tent\v\n", Out.data());
168+
EXPECT_STREQ("#define MACRO() con \v tent\n", Out.data());
169169

170170
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
171171
"#define MACRO \t\v\f\v\t con\f\t\vtent\v\f \v", Out));
172-
EXPECT_STREQ("#define MACRO con\f\t\vtent\v\n", Out.data());
172+
EXPECT_STREQ("#define MACRO con\f\t\vtent\n", Out.data());
173173
}
174174

175175
TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgs) {
@@ -476,6 +476,17 @@ TEST(MinimizeSourceToDependencyDirectivesTest, SplitIdentifier) {
476476
EXPECT_STREQ("#define GUA RD\n", Out.data());
477477
}
478478

479+
TEST(MinimizeSourceToDependencyDirectivesTest,
480+
WhitespaceAfterLineContinuationSlash) {
481+
SmallVector<char, 128> Out;
482+
483+
ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n"
484+
"2 + \\\t\n"
485+
"3\n",
486+
Out));
487+
EXPECT_STREQ("#define A 1 + 2 + 3\n", Out.data());
488+
}
489+
479490
TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
480491
SmallVector<char, 128> Out;
481492

0 commit comments

Comments
 (0)