17
17
#include " clang/Frontend/FrontendActions.h"
18
18
#include " clang/Lex/PreprocessorOptions.h"
19
19
#include " llvm/ADT/StringRef.h"
20
+ #include " llvm/Support/Error.h"
20
21
#include " llvm/Support/FormatVariadic.h"
21
22
#include " llvm/Support/Path.h"
22
23
#include " gmock/gmock.h"
@@ -29,8 +30,10 @@ namespace {
29
30
using ::testing::AllOf;
30
31
using ::testing::Contains;
31
32
using ::testing::ElementsAre;
33
+ using ::testing::IsEmpty;
32
34
using ::testing::Not;
33
35
using ::testing::UnorderedElementsAre;
36
+ using ::testing::UnorderedElementsAreArray;
34
37
35
38
class HeadersTest : public ::testing::Test {
36
39
public:
@@ -64,8 +67,15 @@ class HeadersTest : public ::testing::Test {
64
67
}
65
68
66
69
protected:
70
+ IncludeStructure::HeaderID getID (StringRef Filename,
71
+ IncludeStructure &Includes) {
72
+ auto Entry = Clang->getSourceManager ().getFileManager ().getFile (Filename);
73
+ EXPECT_TRUE (Entry);
74
+ return Includes.getOrCreateID (*Entry);
75
+ }
76
+
67
77
IncludeStructure collectIncludes () {
68
- auto Clang = setupClang ();
78
+ Clang = setupClang ();
69
79
PreprocessOnlyAction Action;
70
80
EXPECT_TRUE (
71
81
Action.BeginSourceFile (*Clang, Clang->getFrontendOpts ().Inputs [0 ]));
@@ -81,7 +91,7 @@ class HeadersTest : public ::testing::Test {
81
91
// inserted.
82
92
std::string calculate (PathRef Original, PathRef Preferred = " " ,
83
93
const std::vector<Inclusion> &Inclusions = {}) {
84
- auto Clang = setupClang ();
94
+ Clang = setupClang ();
85
95
PreprocessOnlyAction Action;
86
96
EXPECT_TRUE (
87
97
Action.BeginSourceFile (*Clang, Clang->getFrontendOpts ().Inputs [0 ]));
@@ -107,7 +117,7 @@ class HeadersTest : public ::testing::Test {
107
117
}
108
118
109
119
llvm::Optional<TextEdit> insert (llvm::StringRef VerbatimHeader) {
110
- auto Clang = setupClang ();
120
+ Clang = setupClang ();
111
121
PreprocessOnlyAction Action;
112
122
EXPECT_TRUE (
113
123
Action.BeginSourceFile (*Clang, Clang->getFrontendOpts ().Inputs [0 ]));
@@ -126,6 +136,7 @@ class HeadersTest : public ::testing::Test {
126
136
std::string Subdir = testPath(" sub" );
127
137
std::string SearchDirArg = (llvm::Twine(" -I" ) + Subdir).str();
128
138
IgnoringDiagConsumer IgnoreDiags;
139
+ std::unique_ptr<CompilerInstance> Clang;
129
140
};
130
141
131
142
MATCHER_P (Written, Name, " " ) { return arg.Written == Name; }
@@ -134,11 +145,11 @@ MATCHER_P(IncludeLine, N, "") { return arg.HashLine == N; }
134
145
MATCHER_P (Directive, D, " " ) { return arg.Directive == D; }
135
146
136
147
MATCHER_P2 (Distance, File, D, " " ) {
137
- if (arg.getKey () != File)
138
- *result_listener << " file =" << arg.getKey (). str ( );
139
- if (arg.getValue () != D)
140
- *result_listener << " distance =" << arg.getValue ();
141
- return arg.getKey () == File && arg.getValue () == D;
148
+ if (arg.getFirst () != File)
149
+ *result_listener << " file =" << static_cast < unsigned >( arg.getFirst () );
150
+ if (arg.getSecond () != D)
151
+ *result_listener << " distance =" << arg.getSecond ();
152
+ return arg.getFirst () == File && arg.getSecond () == D;
142
153
}
143
154
144
155
TEST_F (HeadersTest, CollectRewrittenAndResolved) {
@@ -148,12 +159,14 @@ TEST_F(HeadersTest, CollectRewrittenAndResolved) {
148
159
std::string BarHeader = testPath (" sub/bar.h" );
149
160
FS.Files [BarHeader] = " " ;
150
161
151
- EXPECT_THAT (collectIncludes ().MainFileIncludes ,
162
+ auto Includes = collectIncludes ();
163
+ EXPECT_THAT (Includes.MainFileIncludes ,
152
164
UnorderedElementsAre (
153
165
AllOf (Written (" \" sub/bar.h\" " ), Resolved (BarHeader))));
154
- EXPECT_THAT (collectIncludes ().includeDepth (MainFile),
155
- UnorderedElementsAre (Distance (MainFile, 0u ),
156
- Distance (testPath (" sub/bar.h" ), 1u )));
166
+ EXPECT_THAT (collectIncludes ().includeDepth (getID (MainFile, Includes)),
167
+ UnorderedElementsAre (
168
+ Distance (getID (MainFile, Includes), 0u ),
169
+ Distance (getID (testPath (" sub/bar.h" ), Includes), 1u )));
157
170
}
158
171
159
172
TEST_F (HeadersTest, OnlyCollectInclusionsInMain) {
@@ -166,17 +179,21 @@ TEST_F(HeadersTest, OnlyCollectInclusionsInMain) {
166
179
FS.Files [MainFile] = R"cpp(
167
180
#include "bar.h"
168
181
)cpp" ;
182
+ auto Includes = collectIncludes ();
169
183
EXPECT_THAT (
170
184
collectIncludes ().MainFileIncludes ,
171
185
UnorderedElementsAre (AllOf (Written (" \" bar.h\" " ), Resolved (BarHeader))));
172
- EXPECT_THAT (collectIncludes ().includeDepth (MainFile),
173
- UnorderedElementsAre (Distance (MainFile, 0u ),
174
- Distance (testPath (" sub/bar.h" ), 1u ),
175
- Distance (testPath (" sub/baz.h" ), 2u )));
186
+ EXPECT_THAT (Includes.includeDepth (getID (MainFile, Includes)),
187
+ UnorderedElementsAre (
188
+ Distance (getID (MainFile, Includes), 0u ),
189
+ Distance (getID (testPath (" sub/bar.h" ), Includes), 1u ),
190
+ Distance (getID (testPath (" sub/baz.h" ), Includes), 2u )));
176
191
// includeDepth() also works for non-main files.
177
- EXPECT_THAT (collectIncludes ().includeDepth (testPath (" sub/bar.h" )),
178
- UnorderedElementsAre (Distance (testPath (" sub/bar.h" ), 0u ),
179
- Distance (testPath (" sub/baz.h" ), 1u )));
192
+ EXPECT_THAT (
193
+ collectIncludes ().includeDepth (getID (testPath (" sub/bar.h" ), Includes)),
194
+ UnorderedElementsAre (
195
+ Distance (getID (testPath (" sub/bar.h" ), Includes), 0u ),
196
+ Distance (getID (testPath (" sub/baz.h" ), Includes), 1u )));
180
197
}
181
198
182
199
TEST_F (HeadersTest, PreambleIncludesPresentOnce) {
@@ -202,8 +219,32 @@ TEST_F(HeadersTest, UnResolvedInclusion) {
202
219
203
220
EXPECT_THAT (collectIncludes ().MainFileIncludes ,
204
221
UnorderedElementsAre (AllOf (Written (" \" foo.h\" " ), Resolved (" " ))));
205
- EXPECT_THAT (collectIncludes ().includeDepth (MainFile),
206
- UnorderedElementsAre (Distance (MainFile, 0u )));
222
+ EXPECT_THAT (collectIncludes ().IncludeChildren , IsEmpty ());
223
+ }
224
+
225
+ TEST_F (HeadersTest, IncludedFilesGraph) {
226
+ FS.Files [MainFile] = R"cpp(
227
+ #include "bar.h"
228
+ #include "foo.h"
229
+ )cpp" ;
230
+ std::string BarHeader = testPath (" bar.h" );
231
+ FS.Files [BarHeader] = " " ;
232
+ std::string FooHeader = testPath (" foo.h" );
233
+ FS.Files [FooHeader] = R"cpp(
234
+ #include "bar.h"
235
+ #include "baz.h"
236
+ )cpp" ;
237
+ std::string BazHeader = testPath (" baz.h" );
238
+ FS.Files [BazHeader] = " " ;
239
+
240
+ auto Includes = collectIncludes ();
241
+ llvm::DenseMap<IncludeStructure::HeaderID,
242
+ SmallVector<IncludeStructure::HeaderID>>
243
+ Expected = {{getID (MainFile, Includes),
244
+ {getID (BarHeader, Includes), getID (FooHeader, Includes)}},
245
+ {getID (FooHeader, Includes),
246
+ {getID (BarHeader, Includes), getID (BazHeader, Includes)}}};
247
+ EXPECT_EQ (Includes.IncludeChildren , Expected);
207
248
}
208
249
209
250
TEST_F (HeadersTest, IncludeDirective) {
0 commit comments