From b9eae4c1d738b05cd5837a75e514a9c79468312a Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Mon, 13 May 2013 09:22:11 +0000 Subject: [PATCH] Implements UseTab for clang-format. This is required for kernel linux kernel style formatting. llvm-svn: 181693 --- clang/include/clang/Format/Format.h | 7 ++++++- clang/lib/Format/Format.cpp | 3 +++ clang/lib/Format/WhitespaceManager.cpp | 12 ++++++++++-- clang/lib/Format/WhitespaceManager.h | 2 ++ clang/unittests/Format/FormatTest.cpp | 22 ++++++++++++++++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index dd8f6661801c..79e26d0a0c6a 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -97,6 +97,10 @@ struct FormatStyle { /// \brief The number of characters to use for indentation. unsigned IndentWidth; + /// \brief If true, \c IndentWidth consecutive spaces will be replaced with + /// tab characters. + bool UseTab; + bool operator==(const FormatStyle &R) const { return AccessModifierOffset == R.AccessModifierOffset && AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft && @@ -117,7 +121,8 @@ struct FormatStyle { PointerBindsToType == R.PointerBindsToType && SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments && Standard == R.Standard && - IndentWidth == IndentWidth; + IndentWidth == R.IndentWidth && + UseTab == R.UseTab; } }; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f3ca9c371f1e..2f2f095780dc 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -86,6 +86,7 @@ template <> struct MappingTraits { Style.SpacesBeforeTrailingComments); IO.mapOptional("Standard", Style.Standard); IO.mapOptional("IndentWidth", Style.IndentWidth); + IO.mapOptional("UseTab", Style.UseTab); } }; } @@ -113,6 +114,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.SpacesBeforeTrailingComments = 1; LLVMStyle.Standard = FormatStyle::LS_Cpp03; LLVMStyle.IndentWidth = 2; + LLVMStyle.UseTab = false; return LLVMStyle; } @@ -135,6 +137,7 @@ FormatStyle getGoogleStyle() { GoogleStyle.SpacesBeforeTrailingComments = 2; GoogleStyle.Standard = FormatStyle::LS_Auto; GoogleStyle.IndentWidth = 2; + GoogleStyle.UseTab = false; return GoogleStyle; } diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index a75c592bfeda..21e38b1e979e 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -122,7 +122,7 @@ void WhitespaceManager::addUntouchableComment(unsigned Column) { std::string WhitespaceManager::getNewLineText(unsigned NewLines, unsigned Spaces) { - return std::string(NewLines, '\n') + std::string(Spaces, ' '); + return std::string(NewLines, '\n') + getIndentText(Spaces); } std::string WhitespaceManager::getNewLineText(unsigned NewLines, @@ -139,7 +139,15 @@ std::string WhitespaceManager::getNewLineText(unsigned NewLines, Offset = 0; } } - return NewLineText + std::string(Spaces, ' '); + return NewLineText + getIndentText(Spaces); +} + +std::string WhitespaceManager::getIndentText(unsigned Spaces) { + if (!Style.UseTab) { + return std::string(Spaces, ' '); + } + return std::string(Spaces / Style.IndentWidth, '\t') + + std::string(Spaces % Style.IndentWidth, ' '); } void WhitespaceManager::alignComments() { diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h index 5f3dc55edacc..1b24b3f6d79d 100644 --- a/clang/lib/Format/WhitespaceManager.h +++ b/clang/lib/Format/WhitespaceManager.h @@ -78,6 +78,8 @@ private: unsigned WhitespaceStartColumn, unsigned EscapedNewlineColumn); + std::string getIndentText(unsigned Spaces); + /// \brief Structure to store tokens for later layout and alignment. struct StoredToken { StoredToken(SourceLocation ReplacementLoc, unsigned ReplacementLength, diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 931d29dd3e7c..ce79a1c97b99 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -4016,6 +4016,27 @@ TEST_F(FormatTest, ConfigurableIndentWidth) { EightIndent); } +TEST_F(FormatTest, ConfigurableUseOfTab) { + FormatStyle Tab = getLLVMStyleWithColumns(42); + Tab.IndentWidth = 8; + Tab.UseTab = true; + Tab.AlignEscapedNewlinesLeft = true; + 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); +} + bool allStylesEqual(ArrayRef Styles) { for (size_t i = 1; i < Styles.size(); ++i) if (!(Styles[0] == Styles[i])) @@ -4070,6 +4091,7 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE_BOOL(IndentCaseLabels); CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList); CHECK_PARSE_BOOL(PointerBindsToType); + CHECK_PARSE_BOOL(UseTab); CHECK_PARSE("AccessModifierOffset: -1234", AccessModifierOffset, -1234); CHECK_PARSE("ColumnLimit: 1234", ColumnLimit, 1234u);