summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Lex/DependencyDirectivesSourceMinimizer.cpp33
-rw-r--r--clang/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp19
2 files changed, 37 insertions, 15 deletions
diff --git a/clang/lib/Lex/DependencyDirectivesSourceMinimizer.cpp b/clang/lib/Lex/DependencyDirectivesSourceMinimizer.cpp
index 2a3c88251bc..2ffbcfb7e67 100644
--- a/clang/lib/Lex/DependencyDirectivesSourceMinimizer.cpp
+++ b/clang/lib/Lex/DependencyDirectivesSourceMinimizer.cpp
@@ -244,14 +244,20 @@ static void skipToNewlineRaw(const char *&First, const char *const End) {
}
}
-static const char *reverseOverSpaces(const char *First, const char *Last) {
+static const char *findLastNonSpace(const char *First, const char *Last) {
assert(First <= Last);
- const char *PrevLast = Last;
- while (First != Last && isHorizontalWhitespace(Last[-1])) {
- PrevLast = Last;
+ while (First != Last && isHorizontalWhitespace(Last[-1]))
--Last;
- }
- return PrevLast;
+ return Last;
+}
+
+static const char *findFirstTrailingSpace(const char *First,
+ const char *Last) {
+ const char *LastNonSpace = findLastNonSpace(First, Last);
+ if (Last == LastNonSpace)
+ return Last;
+ assert(isHorizontalWhitespace(LastNonSpace[0]));
+ return LastNonSpace + 1;
}
static void skipLineComment(const char *&First, const char *const End) {
@@ -385,7 +391,7 @@ void Minimizer::printToNewline(const char *&First, const char *const End) {
}
// Deal with "//..." and "/*...*/".
- append(First, reverseOverSpaces(First, Last));
+ append(First, findFirstTrailingSpace(First, Last));
First = Last;
if (Last[1] == '/') {
@@ -400,15 +406,20 @@ void Minimizer::printToNewline(const char *&First, const char *const End) {
} while (Last != End && !isVerticalWhitespace(*Last));
// Print out the string.
- if (Last == End || Last == First || Last[-1] != '\\') {
- append(First, reverseOverSpaces(First, Last));
+ const char *LastBeforeTrailingSpace = findLastNonSpace(First, Last);
+ if (Last == End || LastBeforeTrailingSpace == First ||
+ LastBeforeTrailingSpace[-1] != '\\') {
+ append(First, LastBeforeTrailingSpace);
First = Last;
skipNewline(First, End);
return;
}
- // Print up to the backslash, backing up over spaces.
- append(First, reverseOverSpaces(First, Last - 1));
+ // Print up to the backslash, backing up over spaces. Preserve at least one
+ // space, as the space matters when tokens are separated by a line
+ // continuation.
+ append(First, findFirstTrailingSpace(
+ First, LastBeforeTrailingSpace - 1));
First = Last;
skipNewline(First, End);
diff --git a/clang/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp b/clang/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp
index c00c160977e..5eb7d256a36 100644
--- a/clang/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp
+++ b/clang/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp
@@ -157,19 +157,19 @@ TEST(MinimizeSourceToDependencyDirectivesTest, DefineHorizontalWhitespace) {
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO(\t)\tcon \t tent\t", Out));
- EXPECT_STREQ("#define MACRO() con \t tent\t\n", Out.data());
+ EXPECT_STREQ("#define MACRO() con \t tent\n", Out.data());
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO(\f)\fcon \f tent\f", Out));
- EXPECT_STREQ("#define MACRO() con \f tent\f\n", Out.data());
+ EXPECT_STREQ("#define MACRO() con \f tent\n", Out.data());
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO(\v)\vcon \v tent\v", Out));
- EXPECT_STREQ("#define MACRO() con \v tent\v\n", Out.data());
+ EXPECT_STREQ("#define MACRO() con \v tent\n", Out.data());
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO \t\v\f\v\t con\f\t\vtent\v\f \v", Out));
- EXPECT_STREQ("#define MACRO con\f\t\vtent\v\n", Out.data());
+ EXPECT_STREQ("#define MACRO con\f\t\vtent\n", Out.data());
}
TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgs) {
@@ -476,6 +476,17 @@ TEST(MinimizeSourceToDependencyDirectivesTest, SplitIdentifier) {
EXPECT_STREQ("#define GUA RD\n", Out.data());
}
+TEST(MinimizeSourceToDependencyDirectivesTest,
+ WhitespaceAfterLineContinuationSlash) {
+ SmallVector<char, 128> Out;
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n"
+ "2 + \\\t\n"
+ "3\n",
+ Out));
+ EXPECT_STREQ("#define A 1 + 2 + 3\n", Out.data());
+}
+
TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
SmallVector<char, 128> Out;
OpenPOWER on IntegriCloud