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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits