summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format/UsingDeclarationsSorter.cpp
diff options
context:
space:
mode:
authorKrasimir Georgiev <krasimir@google.com>2017-11-09 15:41:23 +0000
committerKrasimir Georgiev <krasimir@google.com>2017-11-09 15:41:23 +0000
commit818da9bb299cad1a75e5e31dbd96dabb22f54cb8 (patch)
tree1a7c9a1c5b4372a8532403a04a50f554432d27ab /clang/lib/Format/UsingDeclarationsSorter.cpp
parent1696bb65233cdbef0a1138175cd540fc1b86e540 (diff)
downloadbcm5719-llvm-818da9bb299cad1a75e5e31dbd96dabb22f54cb8.tar.gz
bcm5719-llvm-818da9bb299cad1a75e5e31dbd96dabb22f54cb8.zip
[clang-format] Sort using declarations by splitting on '::'
Summary: This patch improves using declarations sorting. Reviewers: bkramer Reviewed By: bkramer Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D39786 llvm-svn: 317794
Diffstat (limited to 'clang/lib/Format/UsingDeclarationsSorter.cpp')
-rw-r--r--clang/lib/Format/UsingDeclarationsSorter.cpp60
1 files changed, 40 insertions, 20 deletions
diff --git a/clang/lib/Format/UsingDeclarationsSorter.cpp b/clang/lib/Format/UsingDeclarationsSorter.cpp
index e9c535da925..72151137eed 100644
--- a/clang/lib/Format/UsingDeclarationsSorter.cpp
+++ b/clang/lib/Format/UsingDeclarationsSorter.cpp
@@ -26,6 +26,45 @@ namespace format {
namespace {
+// The order of using declaration is defined as follows:
+// Split the strings by "::" and discard any initial empty strings. The last
+// element of each list is a non-namespace name; all others are namespace
+// names. Sort the lists of names lexicographically, where the sort order of
+// individual names is that all non-namespace names come before all namespace
+// names, and within those groups, names are in case-insensitive lexicographic
+// order.
+int compareLabels(StringRef A, StringRef B) {
+ SmallVector<StringRef, 2> NamesA;
+ A.split(NamesA, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+ SmallVector<StringRef, 2> NamesB;
+ B.split(NamesB, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+ size_t SizeA = NamesA.size();
+ size_t SizeB = NamesB.size();
+ for (size_t I = 0, E = std::min(SizeA, SizeB); I < E; ++I) {
+ if (I + 1 == SizeA) {
+ // I is the last index of NamesA and NamesA[I] is a non-namespace name.
+
+ // Non-namespace names come before all namespace names.
+ if (SizeB > SizeA)
+ return -1;
+
+ // Two names within a group compare case-insensitively.
+ return NamesA[I].compare_lower(NamesB[I]);
+ }
+
+ // I is the last index of NamesB and NamesB[I] is a non-namespace name.
+ // Non-namespace names come before all namespace names.
+ if (I + 1 == SizeB)
+ return 1;
+
+ // Two namespaces names within a group compare case-insensitively.
+ int C = NamesA[I].compare_lower(NamesB[I]);
+ if (C != 0)
+ return C;
+ }
+ return 0;
+}
+
struct UsingDeclaration {
const AnnotatedLine *Line;
std::string Label;
@@ -33,27 +72,8 @@ struct UsingDeclaration {
UsingDeclaration(const AnnotatedLine *Line, const std::string &Label)
: Line(Line), Label(Label) {}
- // Compares lexicographically with the exception that '_' is just before 'A'.
bool operator<(const UsingDeclaration &Other) const {
- size_t Size = Label.size();
- size_t OtherSize = Other.Label.size();
- for (size_t I = 0, E = std::min(Size, OtherSize); I < E; ++I) {
- char Rank = rank(Label[I]);
- char OtherRank = rank(Other.Label[I]);
- if (Rank != OtherRank)
- return Rank < OtherRank;
- }
- return Size < OtherSize;
- }
-
- // Returns the position of c in a lexicographic ordering with the exception
- // that '_' is just before 'A'.
- static char rank(char c) {
- if (c == '_')
- return 'A';
- if ('A' <= c && c < '_')
- return c + 1;
- return c;
+ return compareLabels(Label, Other.Label) < 0;
}
};
OpenPOWER on IntegriCloud