1 //===------------ IncludeSorter.h - clang-tidy ----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H 11 12 #include "../ClangTidyCheck.h" 13 #include <optional> 14 #include <string> 15 16 namespace clang::tidy { 17 namespace utils { 18 19 /// Class used by ``IncludeInserterCallback`` to record the names of the 20 /// inclusions in a given source file being processed and generate the necessary 21 /// commands to sort the inclusions according to the precedence encoded in 22 /// ``IncludeKinds``. 23 class IncludeSorter { 24 public: 25 /// Supported include styles. 26 enum IncludeStyle { IS_LLVM = 0, IS_Google = 1, IS_Google_ObjC }; 27 28 /// The classifications of inclusions, in the order they should be sorted. 29 enum IncludeKinds { 30 IK_MainTUInclude = 0, ///< e.g. ``#include "foo.h"`` when editing foo.cc 31 IK_CSystemInclude = 1, ///< e.g. ``#include <stdio.h>`` 32 IK_CXXSystemInclude = 2, ///< e.g. ``#include <vector>`` 33 IK_NonSystemInclude = 3, ///< e.g. ``#include "bar.h"`` 34 IK_GeneratedInclude = 4, ///< e.g. ``#include "bar.proto.h"`` 35 IK_InvalidInclude = 5 ///< total number of valid ``IncludeKind``s 36 }; 37 38 /// ``IncludeSorter`` constructor; takes the FileID and name of the file to be 39 /// processed by the sorter. 40 IncludeSorter(const SourceManager *SourceMgr, const FileID FileID, 41 StringRef FileName, IncludeStyle Style); 42 43 /// Adds the given include directive to the sorter. 44 void addInclude(StringRef FileName, bool IsAngled, 45 SourceLocation HashLocation, SourceLocation EndLocation); 46 47 /// Creates a quoted inclusion directive in the right sort order. Returns 48 /// std::nullopt on error or if header inclusion directive for header already 49 /// exists. 50 std::optional<FixItHint> createIncludeInsertion(StringRef FileName, 51 bool IsAngled); 52 53 private: 54 using SourceRangeVector = SmallVector<SourceRange, 1>; 55 56 const SourceManager *SourceMgr; 57 const IncludeStyle Style; 58 FileID CurrentFileID; 59 /// The file name stripped of common suffixes. 60 StringRef CanonicalFile; 61 /// Locations of visited include directives. 62 SourceRangeVector SourceLocations; 63 /// Mapping from file name to #include locations. 64 llvm::StringMap<SourceRangeVector> IncludeLocations; 65 /// Includes sorted into buckets. 66 SmallVector<std::string, 1> IncludeBucket[IK_InvalidInclude]; 67 }; 68 69 } // namespace utils 70 71 template <> struct OptionEnumMapping<utils::IncludeSorter::IncludeStyle> { 72 static ArrayRef<std::pair<utils::IncludeSorter::IncludeStyle, StringRef>> 73 getEnumMapping(); 74 }; 75 } // namespace clang::tidy 76 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H 77