[clang-format] Align block comment decorations

Summary:
This patch implements block comment decoration alignment.

source:
```
/* line 1
* line 2
*/
```

result before:
```
/* line 1
* line 2
*/
```

result after:
```
/* line 1
 * line 2
 */
```

Reviewers: djasper, bkramer, klimek

Reviewed By: klimek

Subscribers: mprobst, cfe-commits, klimek

Differential Revision: https://reviews.llvm.org/D29943

llvm-svn: 295312
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 72fd0df..7497cab 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -1966,7 +1966,7 @@
       format("#define A \\\nint i;\\\n  int j;", getLLVMStyleWithColumns(11)));
   EXPECT_EQ("#define A\n\nint i;", format("#define A \\\n\n int i;"));
   EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();"));
-  EXPECT_EQ("/* \\  \\  \\\n*/", format("\\\n/* \\  \\  \\\n*/"));
+  EXPECT_EQ("/* \\  \\  \\\n */", format("\\\n/* \\  \\  \\\n */"));
   EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>"));
 }
 
diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp
index f5fddaa..0498517 100644
--- a/clang/unittests/Format/FormatTestComments.cpp
+++ b/clang/unittests/Format/FormatTestComments.cpp
@@ -937,11 +937,11 @@
                    getLLVMStyleWithColumns(20)));
 
   EXPECT_EQ("/* some comment\n"
-            "     *   a comment\n"
-            "* that we break\n"
-            " * another comment\n"
-            "* we have to break\n"
-            "* a left comment\n"
+            " *   a comment that\n"
+            " * we break another\n"
+            " * comment we have\n"
+            " * to break a left\n"
+            " * comment\n"
             " */",
             format("  /* some comment\n"
                    "       *   a comment that we break\n"
@@ -1856,10 +1856,10 @@
                    getLLVMStyleWithColumns(15)));
   EXPECT_EQ("/*\n**\n*/", format("/*\n**\n*/"));
   EXPECT_EQ("/*\n"
-            "*\n"
+            " *\n"
             " * aaaaaa\n"
             " * aaaaaa\n"
-            "*/",
+            " */",
             format("/*\n"
                    "*\n"
                    " * aaaaaa aaaaaa\n"
@@ -2164,6 +2164,194 @@
                    "       long b;",
                    getLLVMStyleWithColumns(80)));
 }
+
+TEST_F(FormatTestComments, AlignsBlockCommentDecorations) {
+  EXPECT_EQ("/*\n"
+            " */",
+            format("/*\n"
+                   "*/", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " */",
+            format("/*\n"
+                   " */", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " */",
+            format("/*\n"
+                   "  */", getLLVMStyle()));
+
+  // Align a single line.
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   "* line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   " * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   "  * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   "   * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "* line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   " * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "  * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "   * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "    * line */",
+                   getLLVMStyle()));
+
+  // Align the end '*/' after a line.
+  EXPECT_EQ("/*\n"
+            " * line\n"
+            " */",
+            format("/*\n"
+                   "* line\n"
+                   "*/", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line\n"
+            " */",
+            format("/*\n"
+                   "   * line\n"
+                   "  */", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line\n"
+            " */",
+            format("/*\n"
+                   "  * line\n"
+                   "  */", getLLVMStyle()));
+
+  // Align two lines.
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   " * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "* line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "  * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "   * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "    * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("int i; /* line 1\n"
+            "        * line 2 */",
+            format("int i; /* line 1\n"
+                   "* line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("int i; /* line 1\n"
+            "        * line 2 */",
+            format("int i; /* line 1\n"
+                   "        * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("int i; /* line 1\n"
+            "        * line 2 */",
+            format("int i; /* line 1\n"
+                   "             * line 2 */",
+                   getLLVMStyle()));
+
+  // Align several lines.
+  EXPECT_EQ("/* line 1\n"
+            " * line 2\n"
+            " * line 3 */",
+            format("/* line 1\n"
+                   " * line 2\n"
+                   "* line 3 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2\n"
+            " * line 3 */",
+            format("/* line 1\n"
+                   "  * line 2\n"
+                   "* line 3 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            "** line 1\n"
+            "** line 2\n"
+            "*/",
+            format("/*\n"
+                   "** line 1\n"
+                   " ** line 2\n"
+                   "*/",
+                   getLLVMStyle()));
+
+  // Align with different indent after the decorations.
+  EXPECT_EQ("/*\n"
+            " * line 1\n"
+            " *  line 2\n"
+            " * line 3\n"
+            " *   line 4\n"
+            " */",
+            format("/*\n"
+                   "* line 1\n"
+                   "  *  line 2\n"
+                   "   * line 3\n"
+                   "*   line 4\n"
+                   "*/", getLLVMStyle()));
+
+  // Align empty or blank lines.
+  EXPECT_EQ("/**\n"
+            " *\n"
+            " *\n"
+            " *\n"
+            " */",
+            format("/**\n"
+                   "*  \n"
+                   " * \n"
+                   "  *\n"
+                   "*/", getLLVMStyle()));
+
+  // Align while breaking and reflowing.
+  EXPECT_EQ("/*\n"
+            " * long long long\n"
+            " * long long\n"
+            " *\n"
+            " * long */",
+            format("/*\n"
+                   " * long long long long\n"
+                   " * long\n"
+                   "  *\n"
+                   "* long */",
+                   getLLVMStyleWithColumns(20)));
+}
 } // end namespace
 } // end namespace format
 } // end namespace clang