summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Format/Format.h2
-rw-r--r--clang/lib/Format/Format.cpp2
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp8
-rw-r--r--clang/unittests/Format/FormatTest.cpp226
4 files changed, 238 insertions, 0 deletions
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 2acec268a22..b327d1d0a4b 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -603,6 +603,8 @@ struct FormatStyle {
UT_Never,
/// Use tabs only for indentation.
UT_ForIndentation,
+ /// Use tabs only for line continuation and indentation.
+ UT_ForContinuationAndIndentation,
/// Use tabs whenever we need to fill whitespace that spans at least from
/// one tab stop to the next one.
UT_Always
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index cc11d3df400..66c0812c337 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -69,6 +69,8 @@ template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
IO.enumCase(Value, "Always", FormatStyle::UT_Always);
IO.enumCase(Value, "true", FormatStyle::UT_Always);
IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
+ IO.enumCase(Value, "ForContinuationAndIndentation",
+ FormatStyle::UT_ForContinuationAndIndentation);
}
};
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 0673dfb3ace..9cdba9df10a 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -558,6 +558,14 @@ void WhitespaceManager::appendIndentText(std::string &Text,
}
Text.append(Spaces, ' ');
break;
+ case FormatStyle::UT_ForContinuationAndIndentation:
+ if (WhitespaceStartColumn == 0) {
+ unsigned Tabs = Spaces / Style.TabWidth;
+ Text.append(Tabs, '\t');
+ Spaces -= Tabs * Style.TabWidth;
+ }
+ Text.append(Spaces, ' ');
+ break;
}
}
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 2790f9dab0d..50a83f66ad2 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -8572,6 +8572,230 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
"\t */\n"
"\t int i;\n"
"}"));
+
+ Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation;
+ Tab.TabWidth = 8;
+ Tab.IndentWidth = 8;
+ EXPECT_EQ("if (aaaaaaaa && // q\n"
+ " bb) // w\n"
+ "\t;",
+ format("if (aaaaaaaa &&// q\n"
+ "bb)// w\n"
+ ";",
+ Tab));
+ EXPECT_EQ("if (aaa && bbb) // w\n"
+ "\t;",
+ format("if(aaa&&bbb)// w\n"
+ ";",
+ Tab));
+ verifyFormat("class X {\n"
+ "\tvoid f() {\n"
+ "\t\tsomeFunction(parameter1,\n"
+ "\t\t\t parameter2);\n"
+ "\t}\n"
+ "};",
+ Tab);
+ verifyFormat("#define A \\\n"
+ "\tvoid f() { \\\n"
+ "\t\tsomeFunction( \\\n"
+ "\t\t parameter1, \\\n"
+ "\t\t parameter2); \\\n"
+ "\t}",
+ Tab);
+ Tab.TabWidth = 4;
+ Tab.IndentWidth = 8;
+ verifyFormat("class TabWidth4Indent8 {\n"
+ "\t\tvoid f() {\n"
+ "\t\t\t\tsomeFunction(parameter1,\n"
+ "\t\t\t\t\t\t\t parameter2);\n"
+ "\t\t}\n"
+ "};",
+ Tab);
+ Tab.TabWidth = 4;
+ Tab.IndentWidth = 4;
+ verifyFormat("class TabWidth4Indent4 {\n"
+ "\tvoid f() {\n"
+ "\t\tsomeFunction(parameter1,\n"
+ "\t\t\t\t\t parameter2);\n"
+ "\t}\n"
+ "};",
+ Tab);
+ Tab.TabWidth = 8;
+ Tab.IndentWidth = 4;
+ verifyFormat("class TabWidth8Indent4 {\n"
+ " void f() {\n"
+ "\tsomeFunction(parameter1,\n"
+ "\t\t parameter2);\n"
+ " }\n"
+ "};",
+ Tab);
+ Tab.TabWidth = 8;
+ Tab.IndentWidth = 8;
+ EXPECT_EQ("/*\n"
+ "\t a\t\tcomment\n"
+ "\t in multiple lines\n"
+ " */",
+ format(" /*\t \t \n"
+ " \t \t a\t\tcomment\t \t\n"
+ " \t \t in multiple lines\t\n"
+ " \t */",
+ Tab));
+ verifyFormat("{\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+ "};",
+ Tab);
+ verifyFormat("enum AA {\n"
+ "\ta1, // Force multiple lines\n"
+ "\ta2,\n"
+ "\ta3\n"
+ "};",
+ Tab);
+ EXPECT_EQ("if (aaaaaaaa && // q\n"
+ " bb) // w\n"
+ "\t;",
+ format("if (aaaaaaaa &&// q\n"
+ "bb)// w\n"
+ ";",
+ Tab));
+ verifyFormat("class X {\n"
+ "\tvoid f() {\n"
+ "\t\tsomeFunction(parameter1,\n"
+ "\t\t\t parameter2);\n"
+ "\t}\n"
+ "};",
+ Tab);
+ verifyFormat("{\n"
+ "\tQ(\n"
+ "\t {\n"
+ "\t\t int a;\n"
+ "\t\t someFunction(aaaaaaaa,\n"
+ "\t\t\t\t bbbbbbb);\n"
+ "\t },\n"
+ "\t p);\n"
+ "}",
+ Tab);
+ EXPECT_EQ("{\n"
+ "\t/* aaaa\n"
+ "\t bbbb */\n"
+ "}",
+ format("{\n"
+ "/* aaaa\n"
+ " bbbb */\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "/*\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t// bbbbbbbbbbbbb\n"
+ "}",
+ format("{\n"
+ "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\n"
+ "\t*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ " asdf\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ " asdf\n"
+ "\t*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("/*\n"
+ "\t a\t\tcomment\n"
+ "\t in multiple lines\n"
+ " */",
+ format(" /*\t \t \n"
+ " \t \t a\t\tcomment\t \t\n"
+ " \t \t in multiple lines\t\n"
+ " \t */",
+ Tab));
+ EXPECT_EQ("/* some\n"
+ " comment */",
+ format(" \t \t /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("int a; /* some\n"
+ " comment */",
+ format(" \t \t int a; /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("int a; /* some\n"
+ "comment */",
+ format(" \t \t int\ta; /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("f(\"\t\t\"); /* some\n"
+ " comment */",
+ format(" \t \t f(\"\t\t\"); /* some\n"
+ " \t \t comment */",
+ Tab));
+ EXPECT_EQ("{\n"
+ " /*\n"
+ " * Comment\n"
+ " */\n"
+ " int i;\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\t * Comment\n"
+ "\t */\n"
+ "\t int i;\n"
+ "}"));
+ Tab.AlignConsecutiveAssignments = true;
+ Tab.AlignConsecutiveDeclarations = true;
+ Tab.TabWidth = 4;
+ Tab.IndentWidth = 4;
+ verifyFormat("class Assign {\n"
+ "\tvoid f() {\n"
+ "\t\tint x = 123;\n"
+ "\t\tint random = 4;\n"
+ "\t\tstd::string alphabet =\n"
+ "\t\t\t\"abcdefghijklmnopqrstuvwxyz\";\n"
+ "\t}\n"
+ "};",
+ Tab);
}
TEST_F(FormatTest, CalculatesOriginalColumn) {
@@ -10015,6 +10239,8 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
+ CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab,
+ FormatStyle::UT_ForContinuationAndIndentation);
// For backward compatibility:
CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
OpenPOWER on IntegriCloud