summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Hoad <mydeveloperday@gmail.com>2019-09-25 20:33:01 +0000
committerPaul Hoad <mydeveloperday@gmail.com>2019-09-25 20:33:01 +0000
commit52e44b142362515f62bee1de2961bc3c0e7f62fe (patch)
tree4fa7b90f8a65ed5cebb8874c3b20ce1d413282fc
parent185f56bbbec3001c572e0e19d9787765d30e2429 (diff)
downloadbcm5719-llvm-52e44b142362515f62bee1de2961bc3c0e7f62fe.tar.gz
bcm5719-llvm-52e44b142362515f62bee1de2961bc3c0e7f62fe.zip
[clang-format] Modified SortIncludes and IncludeCategories to priority for sorting #includes within the Group Category.
Summary: This new Style rule is made as a part of adding support for NetBSD KNF in clang-format. NetBSD have it's own priority of includes which should be followed while formatting NetBSD code. This style sorts the Cpp Includes according to the priorities of NetBSD, as mentioned in the [Style Guide](http://cvsweb.netbsd.org/bsdweb.cgi/src/share/misc/style?rev=HEAD&content-type=text/x-cvsweb-markup) The working of this Style rule shown below: **Configuration:** This revision introduces a new field under IncludeCategories named `SortPriority` which defines the priority of ordering the `#includes` and the `Priority` will define the categories for grouping the `#include blocks`. Reviewers: cfe-commits, mgorny, christos, MyDeveloperDay Reviewed By: MyDeveloperDay Subscribers: lebedev.ri, rdwampler, christos, mgorny, krytarowski Patch By: Manikishan Tags: #clang, #clang-format Differential Revision: https://reviews.llvm.org/D64695 llvm-svn: 372919
-rw-r--r--clang/docs/ClangFormatStyleOptions.rst9
-rw-r--r--clang/include/clang/Tooling/Inclusions/HeaderIncludes.h1
-rw-r--r--clang/include/clang/Tooling/Inclusions/IncludeStyle.h2
-rw-r--r--clang/lib/Format/Format.cpp14
-rw-r--r--clang/lib/Tooling/Inclusions/HeaderIncludes.cpp14
-rw-r--r--clang/lib/Tooling/Inclusions/IncludeStyle.cpp1
-rw-r--r--clang/unittests/Format/SortIncludesTest.cpp71
7 files changed, 108 insertions, 4 deletions
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 6a42da71b96..bd50943dfd8 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1511,6 +1511,13 @@ the configuration (without a prefix: ``Auto``).
can also assign negative priorities if you have certain headers that
always need to be first.
+ There is a third and optional field ``SortPriority`` which can used while
+ ``IncludeBloks = IBS_Regroup`` to define the priority in which ``#includes``
+ should be ordered, and value of ``Priority`` defines the order of
+ ``#include blocks`` and also enables to group ``#includes`` of different
+ priority for order.``SortPriority`` is set to the value of ``Priority``
+ as default if it is not assigned.
+
To configure this in the .clang-format file, use:
.. code-block:: yaml
@@ -1518,12 +1525,14 @@ the configuration (without a prefix: ``Auto``).
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
+ SortPriority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '<[[:alnum:].]+>'
Priority: 4
- Regex: '.*'
Priority: 1
+ SortPriority: 0
**IncludeIsMainRegex** (``std::string``)
Specify a regular expression of suffixes that are allowed in the
diff --git a/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h b/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
index ec6f0ea45ff..6e6d6d8fb02 100644
--- a/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
+++ b/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
@@ -32,6 +32,7 @@ public:
/// 0. Otherwise, returns the priority of the matching category or INT_MAX.
/// NOTE: this API is not thread-safe!
int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const;
+ int getSortIncludePriority(StringRef IncludeName, bool CheckMainHeader) const;
private:
bool isMainHeader(StringRef IncludeName) const;
diff --git a/clang/include/clang/Tooling/Inclusions/IncludeStyle.h b/clang/include/clang/Tooling/Inclusions/IncludeStyle.h
index a0f236e6fc4..266763a5b1b 100644
--- a/clang/include/clang/Tooling/Inclusions/IncludeStyle.h
+++ b/clang/include/clang/Tooling/Inclusions/IncludeStyle.h
@@ -58,6 +58,8 @@ struct IncludeStyle {
std::string Regex;
/// The priority to assign to this category.
int Priority;
+ /// The custom priority to sort before grouping.
+ int SortPriority;
bool operator==(const IncludeCategory &Other) const {
return Regex == Other.Regex && Priority == Other.Priority;
}
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index ba76ba083a6..b64d4825240 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1771,6 +1771,7 @@ struct IncludeDirective {
StringRef Text;
unsigned Offset;
int Category;
+ int Priority;
};
struct JavaImportDirective {
@@ -1834,6 +1835,7 @@ static void sortCppIncludes(const FormatStyle &Style,
ArrayRef<tooling::Range> Ranges, StringRef FileName,
StringRef Code, tooling::Replacements &Replaces,
unsigned *Cursor) {
+ tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
unsigned IncludesBeginOffset = Includes.front().Offset;
unsigned IncludesEndOffset =
Includes.back().Offset + Includes.back().Text.size();
@@ -1841,11 +1843,12 @@ static void sortCppIncludes(const FormatStyle &Style,
if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
return;
SmallVector<unsigned, 16> Indices;
- for (unsigned i = 0, e = Includes.size(); i != e; ++i)
+ for (unsigned i = 0, e = Includes.size(); i != e; ++i) {
Indices.push_back(i);
+ }
llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
- return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) <
- std::tie(Includes[RHSI].Category, Includes[RHSI].Filename);
+ return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
+ std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
});
// The index of the include on which the cursor will be put after
// sorting/deduplicating.
@@ -1960,9 +1963,12 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
int Category = Categories.getIncludePriority(
IncludeName,
/*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
+ int Priority = Categories.getSortIncludePriority(
+ IncludeName, !MainIncludeFound && FirstIncludeBlock);
if (Category == 0)
MainIncludeFound = true;
- IncludesInBlock.push_back({IncludeName, Line, Prev, Category});
+ IncludesInBlock.push_back(
+ {IncludeName, Line, Prev, Category, Priority});
} else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
Replaces, Cursor);
diff --git a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
index a7f79c33bc5..e746bbb7f87 100644
--- a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
+++ b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
@@ -199,6 +199,20 @@ int IncludeCategoryManager::getIncludePriority(StringRef IncludeName,
return Ret;
}
+int IncludeCategoryManager::getSortIncludePriority(StringRef IncludeName,
+ bool CheckMainHeader) const {
+ int Ret = INT_MAX;
+ for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i)
+ if (CategoryRegexs[i].match(IncludeName)) {
+ Ret = Style.IncludeCategories[i].SortPriority;
+ if (Ret == 0)
+ Ret = Style.IncludeCategories[i].Priority;
+ break;
+ }
+ if (CheckMainHeader && IsMainFile && Ret > 0 && isMainHeader(IncludeName))
+ Ret = 0;
+ return Ret;
+}
bool IncludeCategoryManager::isMainHeader(StringRef IncludeName) const {
if (!IncludeName.startswith("\""))
return false;
diff --git a/clang/lib/Tooling/Inclusions/IncludeStyle.cpp b/clang/lib/Tooling/Inclusions/IncludeStyle.cpp
index c53c82c8363..26dc0b87cf9 100644
--- a/clang/lib/Tooling/Inclusions/IncludeStyle.cpp
+++ b/clang/lib/Tooling/Inclusions/IncludeStyle.cpp
@@ -17,6 +17,7 @@ void MappingTraits<IncludeStyle::IncludeCategory>::mapping(
IO &IO, IncludeStyle::IncludeCategory &Category) {
IO.mapOptional("Regex", Category.Regex);
IO.mapOptional("Priority", Category.Priority);
+ IO.mapOptional("SortPriority", Category.SortPriority);
}
void ScalarEnumerationTraits<IncludeStyle::IncludeBlocksStyle>::enumeration(
diff --git a/clang/unittests/Format/SortIncludesTest.cpp b/clang/unittests/Format/SortIncludesTest.cpp
index c00d3cb747d..ef67586f1f0 100644
--- a/clang/unittests/Format/SortIncludesTest.cpp
+++ b/clang/unittests/Format/SortIncludesTest.cpp
@@ -70,6 +70,77 @@ TEST_F(SortIncludesTest, BasicSorting) {
{tooling::Range(25, 1)}));
}
+TEST_F(SortIncludesTest, SortedIncludesUsingSortPriorityAttribute) {
+ FmtStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
+ FmtStyle.IncludeStyle.IncludeCategories = {
+ {"^<sys/param\\.h>", 1, 0},
+ {"^<sys/types\\.h>", 1, 1},
+ {"^<sys.*/", 1, 2},
+ {"^<uvm/", 2, 3},
+ {"^<machine/", 3, 4},
+ {"^<dev/", 4, 5},
+ {"^<net.*/", 5, 6},
+ {"^<protocols/", 5, 7},
+ {"^<(fs|miscfs|msdosfs|nfs|ntfs|ufs)/", 6, 8},
+ {"^<(x86|amd64|i386|xen)/", 7, 8},
+ {"<path", 9, 11},
+ {"^<[^/].*\\.h>", 8, 10},
+ {"^\".*\\.h\"", 10, 12}};
+ EXPECT_EQ("#include <sys/param.h>\n"
+ "#include <sys/types.h>\n"
+ "#include <sys/ioctl.h>\n"
+ "#include <sys/socket.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <sys/wait.h>\n"
+ "\n"
+ "#include <net/if.h>\n"
+ "#include <net/if_dl.h>\n"
+ "#include <net/route.h>\n"
+ "#include <netinet/in.h>\n"
+ "#include <protocols/rwhod.h>\n"
+ "\n"
+ "#include <assert.h>\n"
+ "#include <errno.h>\n"
+ "#include <inttypes.h>\n"
+ "#include <stdio.h>\n"
+ "#include <stdlib.h>\n"
+ "\n"
+ "#include <paths.h>\n"
+ "\n"
+ "#include \"pathnames.h\"\n",
+ sort("#include <sys/param.h>\n"
+ "#include <sys/types.h>\n"
+ "#include <sys/ioctl.h>\n"
+ "#include <net/if_dl.h>\n"
+ "#include <net/route.h>\n"
+ "#include <netinet/in.h>\n"
+ "#include <sys/socket.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <sys/wait.h>\n"
+ "#include <net/if.h>\n"
+ "#include <protocols/rwhod.h>\n"
+ "#include <assert.h>\n"
+ "#include <paths.h>\n"
+ "#include \"pathnames.h\"\n"
+ "#include <errno.h>\n"
+ "#include <inttypes.h>\n"
+ "#include <stdio.h>\n"
+ "#include <stdlib.h>\n"));
+}
+TEST_F(SortIncludesTest, SortPriorityNotDefined) {
+ FmtStyle = getLLVMStyle();
+ EXPECT_EQ("#include \"FormatTestUtils.h\"\n"
+ "#include \"clang/Format/Format.h\"\n"
+ "#include \"llvm/ADT/None.h\"\n"
+ "#include \"llvm/Support/Debug.h\"\n"
+ "#include \"gtest/gtest.h\"\n",
+ sort("#include \"clang/Format/Format.h\"\n"
+ "#include \"llvm/ADT/None.h\"\n"
+ "#include \"FormatTestUtils.h\"\n"
+ "#include \"gtest/gtest.h\"\n"
+ "#include \"llvm/Support/Debug.h\"\n"));
+}
+
TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
// Identical #includes have led to a failure with an unstable sort.
std::string Code = "#include <a>\n"
OpenPOWER on IntegriCloud