Index: cfe/trunk/lib/Format/TokenAnnotator.cpp =================================================================== --- cfe/trunk/lib/Format/TokenAnnotator.cpp +++ cfe/trunk/lib/Format/TokenAnnotator.cpp @@ -1725,15 +1725,18 @@ } } - if (NextNonCommentLine && CommentLine) { - // If the comment is currently aligned with the line immediately following - // it, that's probably intentional and we should keep it. - bool AlignedWithNextLine = - NextNonCommentLine->First->NewlinesBefore <= 1 && - NextNonCommentLine->First->OriginalColumn == - (*I)->First->OriginalColumn; - if (AlignedWithNextLine) - (*I)->Level = NextNonCommentLine->Level; + // If the comment is currently aligned with the line immediately following + // it, that's probably intentional and we should keep it. + if (NextNonCommentLine && CommentLine && + NextNonCommentLine->First->NewlinesBefore <= 1 && + NextNonCommentLine->First->OriginalColumn == + (*I)->First->OriginalColumn) { + // Align comments for preprocessor lines with the # in column 0. + // Otherwise, align with the next line. + (*I)->Level = (NextNonCommentLine->Type == LT_PreprocessorDirective || + NextNonCommentLine->Type == LT_ImportStatement) + ? 0 + : NextNonCommentLine->Level; } else { NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr; } Index: cfe/trunk/unittests/Format/FormatTest.cpp =================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp +++ cfe/trunk/unittests/Format/FormatTest.cpp @@ -2595,21 +2595,85 @@ "code();\n" "#endif", Style)); - // FIXME: The comment indent corrector in TokenAnnotator gets thrown off by - // preprocessor indentation. - EXPECT_EQ("#if 1\n" - " // comment\n" - "# define A 0\n" - "// comment\n" - "# define B 0\n" - "#endif", - format("#if 1\n" - "// comment\n" - "# define A 0\n" - " // comment\n" - "# define B 0\n" - "#endif", - Style)); + // Keep comments aligned with #, otherwise indent comments normally. These + // tests cannot use verifyFormat because messUp manipulates leading + // whitespace. + { + const char *Expected = "" + "void f() {\n" + "#if 1\n" + "// Preprocessor aligned.\n" + "# define A 0\n" + " // Code. Separated by blank line.\n" + "\n" + "# define B 0\n" + " // Code. Not aligned with #\n" + "# define C 0\n" + "#endif"; + const char *ToFormat = "" + "void f() {\n" + "#if 1\n" + "// Preprocessor aligned.\n" + "# define A 0\n" + "// Code. Separated by blank line.\n" + "\n" + "# define B 0\n" + " // Code. Not aligned with #\n" + "# define C 0\n" + "#endif"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } + // Keep block quotes aligned. + { + const char *Expected = "" + "void f() {\n" + "#if 1\n" + "/* Preprocessor aligned. */\n" + "# define A 0\n" + " /* Code. Separated by blank line. */\n" + "\n" + "# define B 0\n" + " /* Code. Not aligned with # */\n" + "# define C 0\n" + "#endif"; + const char *ToFormat = "" + "void f() {\n" + "#if 1\n" + "/* Preprocessor aligned. */\n" + "# define A 0\n" + "/* Code. Separated by blank line. */\n" + "\n" + "# define B 0\n" + " /* Code. Not aligned with # */\n" + "# define C 0\n" + "#endif"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } + // Keep comments aligned with un-indented directives. + { + const char *Expected = "" + "void f() {\n" + "// Preprocessor aligned.\n" + "#define A 0\n" + " // Code. Separated by blank line.\n" + "\n" + "#define B 0\n" + " // Code. Not aligned with #\n" + "#define C 0\n"; + const char *ToFormat = "" + "void f() {\n" + "// Preprocessor aligned.\n" + "#define A 0\n" + "// Code. Separated by blank line.\n" + "\n" + "#define B 0\n" + " // Code. Not aligned with #\n" + "#define C 0\n"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } // Test with tabs. Style.UseTab = FormatStyle::UT_Always; Style.IndentWidth = 8;