Index: include/clang/Tooling/Inclusions/HeaderIncludes.h =================================================================== --- include/clang/Tooling/Inclusions/HeaderIncludes.h +++ include/clang/Tooling/Inclusions/HeaderIncludes.h @@ -32,7 +32,7 @@ /// 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) const; private: bool isMainHeader(StringRef IncludeName) const; Index: include/clang/Tooling/Inclusions/IncludeStyle.h =================================================================== --- include/clang/Tooling/Inclusions/IncludeStyle.h +++ include/clang/Tooling/Inclusions/IncludeStyle.h @@ -58,6 +58,8 @@ 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; } Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -1023,6 +1023,39 @@ return Style; } +FormatStyle getNetBSDStyle() { + FormatStyle NetBSDStyle = getLLVMStyle(); + NetBSDStyle.AlignTrailingComments = true; + NetBSDStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; + NetBSDStyle.AlignConsecutiveMacros = true; + NetBSDStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla; + NetBSDStyle.ColumnLimit = 80; + NetBSDStyle.ContinuationIndentWidth = 4; + NetBSDStyle.Cpp11BracedListStyle = false; + NetBSDStyle.FixNamespaceComments = true; + NetBSDStyle.IndentCaseLabels = false; + NetBSDStyle.IndentWidth = 8; + NetBSDStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; + NetBSDStyle.IncludeStyle.IncludeCategories = { + {"^", 1, 0}, + {"^", 1, 1}, + {"^", 9, 11}, + {"^\"\w.*\.h\"$", 10, 12}}; + NetBSDStyle.SortIncludes = true; + NetBSDStyle.TabWidth = 8; + NetBSDStyle.UseTab = FormatStyle::UT_Always; + return NetBSDStyle; +} + FormatStyle getNoStyle() { FormatStyle NoStyle = getLLVMStyle(); NoStyle.DisableFormat = true; @@ -1047,6 +1080,8 @@ *Style = getGNUStyle(); } else if (Name.equals_lower("microsoft")) { *Style = getMicrosoftStyle(Language); + } else if (Name.equals_lower("netbsd")) { + *Style = getNetBSDStyle(); } else if (Name.equals_lower("none")) { *Style = getNoStyle(); } else { @@ -1774,8 +1809,9 @@ static void sortCppIncludes(const FormatStyle &Style, const SmallVectorImpl &Includes, ArrayRef Ranges, StringRef FileName, - StringRef Code, - tooling::Replacements &Replaces, unsigned *Cursor) { + 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(); @@ -1783,11 +1819,15 @@ if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) return; SmallVector Indices; - for (unsigned i = 0, e = Includes.size(); i != e; ++i) + SmallVector IncludesPriority; + for (unsigned i = 0, e = Includes.size(); i != e; ++i) { + IncludesPriority.push_back( + Categories.getSortIncludePriority(Includes[i].Filename)); 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(IncludesPriority[LHSI], Includes[LHSI].Filename) < + std::tie(IncludesPriority[RHSI], Includes[RHSI].Filename); }); // The index of the include on which the cursor will be put after // sorting/deduplicating. Index: lib/Tooling/Inclusions/HeaderIncludes.cpp =================================================================== --- lib/Tooling/Inclusions/HeaderIncludes.cpp +++ lib/Tooling/Inclusions/HeaderIncludes.cpp @@ -199,6 +199,15 @@ return Ret; } +int IncludeCategoryManager::getSortIncludePriority(StringRef IncludeName) 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; + break; + } + return Ret; +} bool IncludeCategoryManager::isMainHeader(StringRef IncludeName) const { if (!IncludeName.startswith("\"")) return false; Index: lib/Tooling/Inclusions/IncludeStyle.cpp =================================================================== --- lib/Tooling/Inclusions/IncludeStyle.cpp +++ lib/Tooling/Inclusions/IncludeStyle.cpp @@ -17,6 +17,7 @@ IO &IO, IncludeStyle::IncludeCategory &Category) { IO.mapOptional("Regex", Category.Regex); IO.mapOptional("Priority", Category.Priority); + IO.mapOptional("SortPriority", Category.SortPriority); } void ScalarEnumerationTraits::enumeration(