clang 8.0.0

HeaderIncludes.h
Go to the documentation of this file.
1 //===--- HeaderIncludes.h - Insert/Delete #includes for C++ code--*- C++-*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H
11 #define LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H
12
13 #include "clang/Basic/SourceManager.h"
14 #include "clang/Tooling/Core/Replacement.h"
15 #include "clang/Tooling/Inclusions/IncludeStyle.h"
16 #include "llvm/Support/Path.h"
17 #include "llvm/Support/Regex.h"
18 #include <unordered_map>
19
20 namespace clang {
21 namespace tooling {
22
23 /// This class manages priorities of C++ #include categories and calculates
24 /// priorities for headers.
25 /// FIXME(ioeric): move this class into implementation file when clang-format's
26 /// include sorting functions are also moved here.
27 class IncludeCategoryManager {
28 public:
29 IncludeCategoryManager(const IncludeStyle &Style, StringRef FileName);
30
31 /// Returns the priority of the category which \p IncludeName belongs to.
32 /// If \p CheckMainHeader is true and \p IncludeName is a main header, returns
33 /// 0. Otherwise, returns the priority of the matching category or INT_MAX.
34 /// NOTE: this API is not thread-safe!
35 int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const;
36
37 private:
38 bool isMainHeader(StringRef IncludeName) const;
39
40 const IncludeStyle Style;
41 bool IsMainFile;
42 std::string FileName;
43 // This refers to a substring in FileName.
44 StringRef FileStem;
45 // Regex is not thread-safe.
46 mutable SmallVector<llvm::Regex, 4> CategoryRegexs;
47 };
48
49 /// Generates replacements for inserting or deleting #include directives in a
50 /// file.
51 class HeaderIncludes {
52 public:
53 HeaderIncludes(llvm::StringRef FileName, llvm::StringRef Code,
54 const IncludeStyle &Style);
55
56 /// Inserts an #include directive of \p Header into the code. If \p IsAngled
57 /// is true, \p Header will be quoted with <> in the directive; otherwise, it
58 /// will be quoted with "".
59 ///
60 /// When searching for points to insert new header, this ignores #include's
61 /// after the #include block(s) in the beginning of a file to avoid inserting
62 /// headers into code sections where new #include's should not be added by
63 /// default. These code sections include:
64 /// - raw string literals (containing #include).
65 /// - #if blocks.
66 /// - Special #include's among declarations (e.g. functions).
67 ///
68 /// Returns a replacement that inserts the new header into a suitable #include
69 /// block of the same category. This respects the order of the existing
70 /// #includes in the block; if the existing #includes are not already sorted,
71 /// this will simply insert the #include in front of the first #include of the
72 /// same category in the code that should be sorted after \p IncludeName. If
73 /// \p IncludeName already exists (with exactly the same spelling), this
74 /// returns None.
75 llvm::Optional<tooling::Replacement> insert(llvm::StringRef Header,
76 bool IsAngled) const;
77
78 /// Removes all existing #includes of \p Header quoted with <> if \p IsAngled
79 /// is true or "" if \p IsAngled is false.
80 /// This doesn't resolve the header file path; it only deletes #includes with
81 /// exactly the same spelling.
82 tooling::Replacements remove(llvm::StringRef Header, bool IsAngled) const;
83
84 private:
85 struct Include {
86 Include(StringRef Name, tooling::Range R) : Name(Name), R(R) {}
87
88 // An include header quoted with either <> or "".
89 std::string Name;
90 // The range of the whole line of include directive including any eading
91 // whitespaces and trailing comment.
92 tooling::Range R;
93 };
94
95 void addExistingInclude(Include IncludeToAdd, unsigned NextLineOffset);
96
97 std::string FileName;
98 std::string Code;
99
100 // Map from include name (quotation trimmed) to a list of existing includes
101 // (in case there are more than one) with the name in the current file. <x>
102 // and "x" will be treated as the same header when deleting #includes.
103 llvm::StringMap<llvm::SmallVector<Include, 1>> ExistingIncludes;
104
105 /// Map from priorities of #include categories to all #includes in the same
106 /// category. This is used to find #includes of the same category when
107 /// inserting new #includes. #includes in the same categories are sorted in
108 /// in the order they appear in the source file.
109 /// See comment for "FormatStyle::IncludeCategories" for details about include
110 /// priorities.
111 std::unordered_map<int, llvm::SmallVector<const Include *, 8>>
112 IncludesByPriority;
113
114 int FirstIncludeOffset;
115 // All new headers should be inserted after this offset (e.g. after header
116 // guards, file comment).
117 unsigned MinInsertOffset;
118 // Max insertion offset in the original code. For example, we want to avoid
119 // inserting new #includes into the actual code section (e.g. after a
120 // declaration).
121 unsigned MaxInsertOffset;
122 IncludeCategoryManager Categories;
123 // Record the offset of the end of the last include in each category.
124 std::unordered_map<int, int> CategoryEndOffsets;
125
126 // All possible priorities.
127 std::set<int> Priorities;
128
129 // Matches a whole #include directive.
130 llvm::Regex IncludeRegex;
131 };
132
133
134 } // namespace tooling
135 } // namespace clang
136
137 #endif // LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H
SourceManager.h
Defines the SourceManager interface.
clang::tooling::Replacements
Maintains a set of replacements that are conflict-free.
Definition: Replacement.h:210
llvm::Optional
Definition: LLVM.h:38
clang::tooling::HeaderIncludes
Generates replacements for inserting or deleting #include directives in a file.
Definition: HeaderIncludes.h:51
IncludeStyle.h
clang::tooling::Range
A source range independent of the SourceManager.
Definition: Replacement.h:45
clang::tooling::IncludeCategoryManager
This class manages priorities of C++ #include categories and calculates priorities for headers...
Definition: HeaderIncludes.h:27
llvm::SmallVector< llvm::Regex, 4 >
Replacement.h
clang::tooling::IncludeStyle
Style for sorting and grouping C++ #include directives.
Definition: IncludeStyle.h:21
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
clang::tooling::IncludeCategoryManager::IncludeCategoryManager
IncludeCategoryManager(const IncludeStyle &Style, StringRef FileName)
Definition: HeaderIncludes.cpp:152
clang::tooling::IncludeCategoryManager::getIncludePriority
int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const
Returns the priority of the category which IncludeName belongs to.
Definition: HeaderIncludes.cpp:164