[clang] 92bccf5 - [clang-format] Don't use PPIndentWidth inside multi-line macros
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 19 23:54:27 PST 2022
Author: Noah Goldstein
Date: 2022-11-19T23:53:48-08:00
New Revision: 92bccf5d3d2122d57f12dc07d4781e90edefd7ef
URL: https://github.com/llvm/llvm-project/commit/92bccf5d3d2122d57f12dc07d4781e90edefd7ef
DIFF: https://github.com/llvm/llvm-project/commit/92bccf5d3d2122d57f12dc07d4781e90edefd7ef.diff
LOG: [clang-format] Don't use PPIndentWidth inside multi-line macros
Differential Revision: https://reviews.llvm.org/D137181
Added:
Modified:
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/TokenAnnotator.h
clang/lib/Format/UnwrappedLineFormatter.cpp
clang/lib/Format/UnwrappedLineParser.cpp
clang/lib/Format/UnwrappedLineParser.h
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 6c4d908f96c8d..e7280df4c78e4 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5095,8 +5095,9 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
}
void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) const {
- llvm::errs() << "AnnotatedTokens(L=" << Line.Level << ", T=" << Line.Type
- << ", C=" << Line.IsContinuation << "):\n";
+ llvm::errs() << "AnnotatedTokens(L=" << Line.Level << ", P=" << Line.PPLevel
+ << ", T=" << Line.Type << ", C=" << Line.IsContinuation
+ << "):\n";
const FormatToken *Tok = Line.First;
while (Tok) {
llvm::errs() << " M=" << Tok->MustBreakBefore
diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h
index cea9ef78f1b28..3cf2e3817c6a2 100644
--- a/clang/lib/Format/TokenAnnotator.h
+++ b/clang/lib/Format/TokenAnnotator.h
@@ -38,6 +38,7 @@ class AnnotatedLine {
public:
AnnotatedLine(const UnwrappedLine &Line)
: First(Line.Tokens.front().Tok), Level(Line.Level),
+ PPLevel(Line.PPLevel),
MatchingOpeningBlockLineIndex(Line.MatchingOpeningBlockLineIndex),
MatchingClosingBlockLineIndex(Line.MatchingClosingBlockLineIndex),
InPPDirective(Line.InPPDirective),
@@ -129,6 +130,7 @@ class AnnotatedLine {
LineType Type;
unsigned Level;
+ unsigned PPLevel;
size_t MatchingOpeningBlockLineIndex;
size_t MatchingClosingBlockLineIndex;
bool InPPDirective;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index d3aa0625d471a..8e1d907208c08 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -60,12 +60,17 @@ class LevelIndentTracker {
// Update the indent level cache size so that we can rely on it
// having the right size in adjustToUnmodifiedline.
skipLine(Line, /*UnknownIndent=*/true);
- if (Line.InPPDirective ||
- (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
- Line.Type == LT_CommentAbovePPDirective)) {
- unsigned IndentWidth =
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_None &&
+ (Line.InPPDirective ||
+ (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
+ Line.Type == LT_CommentAbovePPDirective))) {
+ unsigned PPIndentWidth =
(Style.PPIndentWidth >= 0) ? Style.PPIndentWidth : Style.IndentWidth;
- Indent = Line.Level * IndentWidth + AdditionalIndent;
+ Indent = Line.InMacroBody
+ ? Line.PPLevel * PPIndentWidth +
+ (Line.Level - Line.PPLevel) * Style.IndentWidth
+ : Line.Level * PPIndentWidth;
+ Indent += AdditionalIndent;
} else {
Indent = getIndent(Line.Level);
}
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 18ec0844db3d4..4dc70e2d56c70 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -197,6 +197,7 @@ class ScopedLineState {
PreBlockLine = std::move(Parser.Line);
Parser.Line = std::make_unique<UnwrappedLine>();
Parser.Line->Level = PreBlockLine->Level;
+ Parser.Line->PPLevel = PreBlockLine->PPLevel;
Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
}
@@ -833,6 +834,9 @@ bool UnwrappedLineParser::mightFitOnOneLine(
delete SavedToken.Tok;
}
+ // If these change PPLevel needs to be used for get correct indentation.
+ assert(!Line.InMacroBody);
+ assert(!Line.InPPDirective);
return Line.Level * Style.IndentWidth + Length <= ColumnLimit;
}
@@ -1270,6 +1274,9 @@ void UnwrappedLineParser::parsePPDefine() {
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
++Line->Level;
+
+ Line->PPLevel = PPBranchLevel + (IncludeGuard == IG_Defined ? 0 : 1);
+ assert((int)Line->PPLevel >= 0);
Line->InMacroBody = true;
// Errors during a preprocessor directive can only affect the layout of the
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index 34f211c9ebb35..88810ad996d35 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -44,6 +44,10 @@ struct UnwrappedLine {
/// The indent level of the \c UnwrappedLine.
unsigned Level;
+ /// The \c PPBranchLevel (adjusted for header guards) if this line is a
+ /// \c InMacroBody line, and 0 otherwise.
+ unsigned PPLevel;
+
/// Whether this \c UnwrappedLine is part of a preprocessor directive.
bool InPPDirective;
/// Whether this \c UnwrappedLine is part of a pramga directive.
@@ -357,7 +361,7 @@ struct UnwrappedLineNode {
};
inline UnwrappedLine::UnwrappedLine()
- : Level(0), InPPDirective(false), InPragmaDirective(false),
+ : Level(0), PPLevel(0), InPPDirective(false), InPragmaDirective(false),
InMacroBody(false), MustBeDeclaration(false),
MatchingOpeningBlockLineIndex(kInvalidIndex) {}
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 9505fa03d3e85..d4150f46d1f58 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -5059,6 +5059,213 @@ TEST_F(FormatTest, IndentsPPDirectiveWithPPIndentWidth) {
" int y = 0;\n"
"}",
style);
+
+ style.IndentPPDirectives = FormatStyle::PPDIS_None;
+ verifyFormat("#ifdef foo\n"
+ "#define bar() \\\n"
+ " if (A) { \\\n"
+ " B(); \\\n"
+ " } \\\n"
+ " C();\n"
+ "#endif",
+ style);
+ verifyFormat("if (emacs) {\n"
+ "#ifdef is\n"
+ "#define lit \\\n"
+ " if (af) { \\\n"
+ " return duh(); \\\n"
+ " }\n"
+ "#endif\n"
+ "}",
+ style);
+ verifyFormat("#if abc\n"
+ "#ifdef foo\n"
+ "#define bar() \\\n"
+ " if (A) { \\\n"
+ " if (B) { \\\n"
+ " C(); \\\n"
+ " } \\\n"
+ " } \\\n"
+ " D();\n"
+ "#endif\n"
+ "#endif",
+ style);
+ verifyFormat("#ifndef foo\n"
+ "#define foo\n"
+ "if (emacs) {\n"
+ "#ifdef is\n"
+ "#define lit \\\n"
+ " if (af) { \\\n"
+ " return duh(); \\\n"
+ " }\n"
+ "#endif\n"
+ "}\n"
+ "#endif",
+ style);
+ verifyFormat("#if 1\n"
+ "#define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }\n"
+ "#endif",
+ style);
+ verifyFormat("#define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }",
+ style);
+
+ style.PPIndentWidth = 2;
+ verifyFormat("#ifdef foo\n"
+ "#define bar() \\\n"
+ " if (A) { \\\n"
+ " B(); \\\n"
+ " } \\\n"
+ " C();\n"
+ "#endif",
+ style);
+ style.IndentWidth = 8;
+ verifyFormat("#ifdef foo\n"
+ "#define bar() \\\n"
+ " if (A) { \\\n"
+ " B(); \\\n"
+ " } \\\n"
+ " C();\n"
+ "#endif",
+ style);
+
+ style.IndentWidth = 1;
+ style.PPIndentWidth = 4;
+ verifyFormat("#if 1\n"
+ "#define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }\n"
+ "#endif",
+ style);
+ verifyFormat("#define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }",
+ style);
+
+ style.IndentWidth = 4;
+ style.PPIndentWidth = 1;
+ style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash;
+ verifyFormat("#ifdef foo\n"
+ "# define bar() \\\n"
+ " if (A) { \\\n"
+ " B(); \\\n"
+ " } \\\n"
+ " C();\n"
+ "#endif",
+ style);
+ verifyFormat("#if abc\n"
+ "# ifdef foo\n"
+ "# define bar() \\\n"
+ " if (A) { \\\n"
+ " if (B) { \\\n"
+ " C(); \\\n"
+ " } \\\n"
+ " } \\\n"
+ " D();\n"
+ "# endif\n"
+ "#endif",
+ style);
+ verifyFormat("#ifndef foo\n"
+ "#define foo\n"
+ "if (emacs) {\n"
+ "#ifdef is\n"
+ "# define lit \\\n"
+ " if (af) { \\\n"
+ " return duh(); \\\n"
+ " }\n"
+ "#endif\n"
+ "}\n"
+ "#endif",
+ style);
+ verifyFormat("#define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }",
+ style);
+
+ style.PPIndentWidth = 2;
+ style.IndentWidth = 8;
+ verifyFormat("#ifdef foo\n"
+ "# define bar() \\\n"
+ " if (A) { \\\n"
+ " B(); \\\n"
+ " } \\\n"
+ " C();\n"
+ "#endif",
+ style);
+
+ style.PPIndentWidth = 4;
+ style.IndentWidth = 1;
+ verifyFormat("#define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }",
+ style);
+
+ style.IndentWidth = 4;
+ style.PPIndentWidth = 1;
+ style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash;
+ verifyFormat("if (emacs) {\n"
+ "#ifdef is\n"
+ " #define lit \\\n"
+ " if (af) { \\\n"
+ " return duh(); \\\n"
+ " }\n"
+ "#endif\n"
+ "}",
+ style);
+ verifyFormat("#if abc\n"
+ " #ifdef foo\n"
+ " #define bar() \\\n"
+ " if (A) { \\\n"
+ " B(); \\\n"
+ " } \\\n"
+ " C();\n"
+ " #endif\n"
+ "#endif",
+ style);
+ verifyFormat("#if 1\n"
+ " #define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }\n"
+ "#endif",
+ style);
+
+ style.PPIndentWidth = 2;
+ verifyFormat("#ifdef foo\n"
+ " #define bar() \\\n"
+ " if (A) { \\\n"
+ " B(); \\\n"
+ " } \\\n"
+ " C();\n"
+ "#endif",
+ style);
+
+ style.PPIndentWidth = 4;
+ style.IndentWidth = 1;
+ verifyFormat("#if 1\n"
+ " #define X \\\n"
+ " { \\\n"
+ " x; \\\n"
+ " x; \\\n"
+ " }\n"
+ "#endif",
+ style);
}
TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) {
More information about the cfe-commits
mailing list