1*0a6a1f1dSLionel Sambuc //===- unittests/libclang/LibclangTest.cpp --- libclang tests -------------===//
2*0a6a1f1dSLionel Sambuc //
3*0a6a1f1dSLionel Sambuc // The LLVM Compiler Infrastructure
4*0a6a1f1dSLionel Sambuc //
5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details.
7*0a6a1f1dSLionel Sambuc //
8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
9*0a6a1f1dSLionel Sambuc
10*0a6a1f1dSLionel Sambuc #include "clang-c/Index.h"
11*0a6a1f1dSLionel Sambuc #include "llvm/Support/Debug.h"
12*0a6a1f1dSLionel Sambuc #include "llvm/Support/FileSystem.h"
13*0a6a1f1dSLionel Sambuc #include "llvm/Support/Path.h"
14*0a6a1f1dSLionel Sambuc #include "llvm/Support/raw_ostream.h"
15*0a6a1f1dSLionel Sambuc #include "gtest/gtest.h"
16*0a6a1f1dSLionel Sambuc #include <fstream>
17*0a6a1f1dSLionel Sambuc #include <set>
18*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "libclang-test"
19*0a6a1f1dSLionel Sambuc
TEST(libclang,clang_parseTranslationUnit2_InvalidArgs)20*0a6a1f1dSLionel Sambuc TEST(libclang, clang_parseTranslationUnit2_InvalidArgs) {
21*0a6a1f1dSLionel Sambuc EXPECT_EQ(CXError_InvalidArguments,
22*0a6a1f1dSLionel Sambuc clang_parseTranslationUnit2(nullptr, nullptr, nullptr, 0, nullptr,
23*0a6a1f1dSLionel Sambuc 0, 0, nullptr));
24*0a6a1f1dSLionel Sambuc }
25*0a6a1f1dSLionel Sambuc
TEST(libclang,clang_createTranslationUnit_InvalidArgs)26*0a6a1f1dSLionel Sambuc TEST(libclang, clang_createTranslationUnit_InvalidArgs) {
27*0a6a1f1dSLionel Sambuc EXPECT_EQ(nullptr, clang_createTranslationUnit(nullptr, nullptr));
28*0a6a1f1dSLionel Sambuc }
29*0a6a1f1dSLionel Sambuc
TEST(libclang,clang_createTranslationUnit2_InvalidArgs)30*0a6a1f1dSLionel Sambuc TEST(libclang, clang_createTranslationUnit2_InvalidArgs) {
31*0a6a1f1dSLionel Sambuc EXPECT_EQ(CXError_InvalidArguments,
32*0a6a1f1dSLionel Sambuc clang_createTranslationUnit2(nullptr, nullptr, nullptr));
33*0a6a1f1dSLionel Sambuc
34*0a6a1f1dSLionel Sambuc CXTranslationUnit TU = reinterpret_cast<CXTranslationUnit>(1);
35*0a6a1f1dSLionel Sambuc EXPECT_EQ(CXError_InvalidArguments,
36*0a6a1f1dSLionel Sambuc clang_createTranslationUnit2(nullptr, nullptr, &TU));
37*0a6a1f1dSLionel Sambuc EXPECT_EQ(nullptr, TU);
38*0a6a1f1dSLionel Sambuc }
39*0a6a1f1dSLionel Sambuc
40*0a6a1f1dSLionel Sambuc namespace {
41*0a6a1f1dSLionel Sambuc struct TestVFO {
42*0a6a1f1dSLionel Sambuc const char *Contents;
43*0a6a1f1dSLionel Sambuc CXVirtualFileOverlay VFO;
44*0a6a1f1dSLionel Sambuc
TestVFO__anon958671300111::TestVFO45*0a6a1f1dSLionel Sambuc TestVFO(const char *Contents) : Contents(Contents) {
46*0a6a1f1dSLionel Sambuc VFO = clang_VirtualFileOverlay_create(0);
47*0a6a1f1dSLionel Sambuc }
48*0a6a1f1dSLionel Sambuc
map__anon958671300111::TestVFO49*0a6a1f1dSLionel Sambuc void map(const char *VPath, const char *RPath) {
50*0a6a1f1dSLionel Sambuc CXErrorCode Err = clang_VirtualFileOverlay_addFileMapping(VFO, VPath, RPath);
51*0a6a1f1dSLionel Sambuc EXPECT_EQ(Err, CXError_Success);
52*0a6a1f1dSLionel Sambuc }
53*0a6a1f1dSLionel Sambuc
mapError__anon958671300111::TestVFO54*0a6a1f1dSLionel Sambuc void mapError(const char *VPath, const char *RPath, CXErrorCode ExpErr) {
55*0a6a1f1dSLionel Sambuc CXErrorCode Err = clang_VirtualFileOverlay_addFileMapping(VFO, VPath, RPath);
56*0a6a1f1dSLionel Sambuc EXPECT_EQ(Err, ExpErr);
57*0a6a1f1dSLionel Sambuc }
58*0a6a1f1dSLionel Sambuc
~TestVFO__anon958671300111::TestVFO59*0a6a1f1dSLionel Sambuc ~TestVFO() {
60*0a6a1f1dSLionel Sambuc if (Contents) {
61*0a6a1f1dSLionel Sambuc char *BufPtr;
62*0a6a1f1dSLionel Sambuc unsigned BufSize;
63*0a6a1f1dSLionel Sambuc clang_VirtualFileOverlay_writeToBuffer(VFO, 0, &BufPtr, &BufSize);
64*0a6a1f1dSLionel Sambuc std::string BufStr(BufPtr, BufSize);
65*0a6a1f1dSLionel Sambuc EXPECT_STREQ(Contents, BufStr.c_str());
66*0a6a1f1dSLionel Sambuc free(BufPtr);
67*0a6a1f1dSLionel Sambuc }
68*0a6a1f1dSLionel Sambuc clang_VirtualFileOverlay_dispose(VFO);
69*0a6a1f1dSLionel Sambuc }
70*0a6a1f1dSLionel Sambuc };
71*0a6a1f1dSLionel Sambuc }
72*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_Basic)73*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_Basic) {
74*0a6a1f1dSLionel Sambuc const char *contents =
75*0a6a1f1dSLionel Sambuc "{\n"
76*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
77*0a6a1f1dSLionel Sambuc " 'roots': [\n"
78*0a6a1f1dSLionel Sambuc " {\n"
79*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
80*0a6a1f1dSLionel Sambuc " 'name': \"/path/virtual\",\n"
81*0a6a1f1dSLionel Sambuc " 'contents': [\n"
82*0a6a1f1dSLionel Sambuc " {\n"
83*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
84*0a6a1f1dSLionel Sambuc " 'name': \"foo.h\",\n"
85*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo.h\"\n"
86*0a6a1f1dSLionel Sambuc " }\n"
87*0a6a1f1dSLionel Sambuc " ]\n"
88*0a6a1f1dSLionel Sambuc " }\n"
89*0a6a1f1dSLionel Sambuc " ]\n"
90*0a6a1f1dSLionel Sambuc "}\n";
91*0a6a1f1dSLionel Sambuc TestVFO T(contents);
92*0a6a1f1dSLionel Sambuc T.map("/path/virtual/foo.h", "/real/foo.h");
93*0a6a1f1dSLionel Sambuc }
94*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_Unicode)95*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_Unicode) {
96*0a6a1f1dSLionel Sambuc const char *contents =
97*0a6a1f1dSLionel Sambuc "{\n"
98*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
99*0a6a1f1dSLionel Sambuc " 'roots': [\n"
100*0a6a1f1dSLionel Sambuc " {\n"
101*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
102*0a6a1f1dSLionel Sambuc " 'name': \"/path/\\u266B\",\n"
103*0a6a1f1dSLionel Sambuc " 'contents': [\n"
104*0a6a1f1dSLionel Sambuc " {\n"
105*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
106*0a6a1f1dSLionel Sambuc " 'name': \"\\u2602.h\",\n"
107*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/\\u2602.h\"\n"
108*0a6a1f1dSLionel Sambuc " }\n"
109*0a6a1f1dSLionel Sambuc " ]\n"
110*0a6a1f1dSLionel Sambuc " }\n"
111*0a6a1f1dSLionel Sambuc " ]\n"
112*0a6a1f1dSLionel Sambuc "}\n";
113*0a6a1f1dSLionel Sambuc TestVFO T(contents);
114*0a6a1f1dSLionel Sambuc T.map("/path/♫/☂.h", "/real/☂.h");
115*0a6a1f1dSLionel Sambuc }
116*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_InvalidArgs)117*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_InvalidArgs) {
118*0a6a1f1dSLionel Sambuc TestVFO T(nullptr);
119*0a6a1f1dSLionel Sambuc T.mapError("/path/./virtual/../foo.h", "/real/foo.h",
120*0a6a1f1dSLionel Sambuc CXError_InvalidArguments);
121*0a6a1f1dSLionel Sambuc }
122*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_RemapDirectories)123*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_RemapDirectories) {
124*0a6a1f1dSLionel Sambuc const char *contents =
125*0a6a1f1dSLionel Sambuc "{\n"
126*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
127*0a6a1f1dSLionel Sambuc " 'roots': [\n"
128*0a6a1f1dSLionel Sambuc " {\n"
129*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
130*0a6a1f1dSLionel Sambuc " 'name': \"/another/dir\",\n"
131*0a6a1f1dSLionel Sambuc " 'contents': [\n"
132*0a6a1f1dSLionel Sambuc " {\n"
133*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
134*0a6a1f1dSLionel Sambuc " 'name': \"foo2.h\",\n"
135*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo2.h\"\n"
136*0a6a1f1dSLionel Sambuc " }\n"
137*0a6a1f1dSLionel Sambuc " ]\n"
138*0a6a1f1dSLionel Sambuc " },\n"
139*0a6a1f1dSLionel Sambuc " {\n"
140*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
141*0a6a1f1dSLionel Sambuc " 'name': \"/path/virtual/dir\",\n"
142*0a6a1f1dSLionel Sambuc " 'contents': [\n"
143*0a6a1f1dSLionel Sambuc " {\n"
144*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
145*0a6a1f1dSLionel Sambuc " 'name': \"foo1.h\",\n"
146*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo1.h\"\n"
147*0a6a1f1dSLionel Sambuc " },\n"
148*0a6a1f1dSLionel Sambuc " {\n"
149*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
150*0a6a1f1dSLionel Sambuc " 'name': \"foo3.h\",\n"
151*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo3.h\"\n"
152*0a6a1f1dSLionel Sambuc " },\n"
153*0a6a1f1dSLionel Sambuc " {\n"
154*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
155*0a6a1f1dSLionel Sambuc " 'name': \"in/subdir\",\n"
156*0a6a1f1dSLionel Sambuc " 'contents': [\n"
157*0a6a1f1dSLionel Sambuc " {\n"
158*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
159*0a6a1f1dSLionel Sambuc " 'name': \"foo4.h\",\n"
160*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo4.h\"\n"
161*0a6a1f1dSLionel Sambuc " }\n"
162*0a6a1f1dSLionel Sambuc " ]\n"
163*0a6a1f1dSLionel Sambuc " }\n"
164*0a6a1f1dSLionel Sambuc " ]\n"
165*0a6a1f1dSLionel Sambuc " }\n"
166*0a6a1f1dSLionel Sambuc " ]\n"
167*0a6a1f1dSLionel Sambuc "}\n";
168*0a6a1f1dSLionel Sambuc TestVFO T(contents);
169*0a6a1f1dSLionel Sambuc T.map("/path/virtual/dir/foo1.h", "/real/foo1.h");
170*0a6a1f1dSLionel Sambuc T.map("/another/dir/foo2.h", "/real/foo2.h");
171*0a6a1f1dSLionel Sambuc T.map("/path/virtual/dir/foo3.h", "/real/foo3.h");
172*0a6a1f1dSLionel Sambuc T.map("/path/virtual/dir/in/subdir/foo4.h", "/real/foo4.h");
173*0a6a1f1dSLionel Sambuc }
174*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_CaseInsensitive)175*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_CaseInsensitive) {
176*0a6a1f1dSLionel Sambuc const char *contents =
177*0a6a1f1dSLionel Sambuc "{\n"
178*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
179*0a6a1f1dSLionel Sambuc " 'case-sensitive': 'false',\n"
180*0a6a1f1dSLionel Sambuc " 'roots': [\n"
181*0a6a1f1dSLionel Sambuc " {\n"
182*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
183*0a6a1f1dSLionel Sambuc " 'name': \"/path/virtual\",\n"
184*0a6a1f1dSLionel Sambuc " 'contents': [\n"
185*0a6a1f1dSLionel Sambuc " {\n"
186*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
187*0a6a1f1dSLionel Sambuc " 'name': \"foo.h\",\n"
188*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo.h\"\n"
189*0a6a1f1dSLionel Sambuc " }\n"
190*0a6a1f1dSLionel Sambuc " ]\n"
191*0a6a1f1dSLionel Sambuc " }\n"
192*0a6a1f1dSLionel Sambuc " ]\n"
193*0a6a1f1dSLionel Sambuc "}\n";
194*0a6a1f1dSLionel Sambuc TestVFO T(contents);
195*0a6a1f1dSLionel Sambuc T.map("/path/virtual/foo.h", "/real/foo.h");
196*0a6a1f1dSLionel Sambuc clang_VirtualFileOverlay_setCaseSensitivity(T.VFO, false);
197*0a6a1f1dSLionel Sambuc }
198*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_SharedPrefix)199*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_SharedPrefix) {
200*0a6a1f1dSLionel Sambuc const char *contents =
201*0a6a1f1dSLionel Sambuc "{\n"
202*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
203*0a6a1f1dSLionel Sambuc " 'roots': [\n"
204*0a6a1f1dSLionel Sambuc " {\n"
205*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
206*0a6a1f1dSLionel Sambuc " 'name': \"/path/foo\",\n"
207*0a6a1f1dSLionel Sambuc " 'contents': [\n"
208*0a6a1f1dSLionel Sambuc " {\n"
209*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
210*0a6a1f1dSLionel Sambuc " 'name': \"bar\",\n"
211*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/bar\"\n"
212*0a6a1f1dSLionel Sambuc " },\n"
213*0a6a1f1dSLionel Sambuc " {\n"
214*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
215*0a6a1f1dSLionel Sambuc " 'name': \"bar.h\",\n"
216*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/bar.h\"\n"
217*0a6a1f1dSLionel Sambuc " }\n"
218*0a6a1f1dSLionel Sambuc " ]\n"
219*0a6a1f1dSLionel Sambuc " },\n"
220*0a6a1f1dSLionel Sambuc " {\n"
221*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
222*0a6a1f1dSLionel Sambuc " 'name': \"/path/foobar\",\n"
223*0a6a1f1dSLionel Sambuc " 'contents': [\n"
224*0a6a1f1dSLionel Sambuc " {\n"
225*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
226*0a6a1f1dSLionel Sambuc " 'name': \"baz.h\",\n"
227*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/baz.h\"\n"
228*0a6a1f1dSLionel Sambuc " }\n"
229*0a6a1f1dSLionel Sambuc " ]\n"
230*0a6a1f1dSLionel Sambuc " },\n"
231*0a6a1f1dSLionel Sambuc " {\n"
232*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
233*0a6a1f1dSLionel Sambuc " 'name': \"/path\",\n"
234*0a6a1f1dSLionel Sambuc " 'contents': [\n"
235*0a6a1f1dSLionel Sambuc " {\n"
236*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
237*0a6a1f1dSLionel Sambuc " 'name': \"foobarbaz.h\",\n"
238*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foobarbaz.h\"\n"
239*0a6a1f1dSLionel Sambuc " }\n"
240*0a6a1f1dSLionel Sambuc " ]\n"
241*0a6a1f1dSLionel Sambuc " }\n"
242*0a6a1f1dSLionel Sambuc " ]\n"
243*0a6a1f1dSLionel Sambuc "}\n";
244*0a6a1f1dSLionel Sambuc TestVFO T(contents);
245*0a6a1f1dSLionel Sambuc T.map("/path/foo/bar.h", "/real/bar.h");
246*0a6a1f1dSLionel Sambuc T.map("/path/foo/bar", "/real/bar");
247*0a6a1f1dSLionel Sambuc T.map("/path/foobar/baz.h", "/real/baz.h");
248*0a6a1f1dSLionel Sambuc T.map("/path/foobarbaz.h", "/real/foobarbaz.h");
249*0a6a1f1dSLionel Sambuc }
250*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_AdjacentDirectory)251*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_AdjacentDirectory) {
252*0a6a1f1dSLionel Sambuc const char *contents =
253*0a6a1f1dSLionel Sambuc "{\n"
254*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
255*0a6a1f1dSLionel Sambuc " 'roots': [\n"
256*0a6a1f1dSLionel Sambuc " {\n"
257*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
258*0a6a1f1dSLionel Sambuc " 'name': \"/path/dir1\",\n"
259*0a6a1f1dSLionel Sambuc " 'contents': [\n"
260*0a6a1f1dSLionel Sambuc " {\n"
261*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
262*0a6a1f1dSLionel Sambuc " 'name': \"foo.h\",\n"
263*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo.h\"\n"
264*0a6a1f1dSLionel Sambuc " },\n"
265*0a6a1f1dSLionel Sambuc " {\n"
266*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
267*0a6a1f1dSLionel Sambuc " 'name': \"subdir\",\n"
268*0a6a1f1dSLionel Sambuc " 'contents': [\n"
269*0a6a1f1dSLionel Sambuc " {\n"
270*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
271*0a6a1f1dSLionel Sambuc " 'name': \"bar.h\",\n"
272*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/bar.h\"\n"
273*0a6a1f1dSLionel Sambuc " }\n"
274*0a6a1f1dSLionel Sambuc " ]\n"
275*0a6a1f1dSLionel Sambuc " }\n"
276*0a6a1f1dSLionel Sambuc " ]\n"
277*0a6a1f1dSLionel Sambuc " },\n"
278*0a6a1f1dSLionel Sambuc " {\n"
279*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
280*0a6a1f1dSLionel Sambuc " 'name': \"/path/dir2\",\n"
281*0a6a1f1dSLionel Sambuc " 'contents': [\n"
282*0a6a1f1dSLionel Sambuc " {\n"
283*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
284*0a6a1f1dSLionel Sambuc " 'name': \"baz.h\",\n"
285*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/baz.h\"\n"
286*0a6a1f1dSLionel Sambuc " }\n"
287*0a6a1f1dSLionel Sambuc " ]\n"
288*0a6a1f1dSLionel Sambuc " }\n"
289*0a6a1f1dSLionel Sambuc " ]\n"
290*0a6a1f1dSLionel Sambuc "}\n";
291*0a6a1f1dSLionel Sambuc TestVFO T(contents);
292*0a6a1f1dSLionel Sambuc T.map("/path/dir1/foo.h", "/real/foo.h");
293*0a6a1f1dSLionel Sambuc T.map("/path/dir1/subdir/bar.h", "/real/bar.h");
294*0a6a1f1dSLionel Sambuc T.map("/path/dir2/baz.h", "/real/baz.h");
295*0a6a1f1dSLionel Sambuc }
296*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_TopLevel)297*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_TopLevel) {
298*0a6a1f1dSLionel Sambuc const char *contents =
299*0a6a1f1dSLionel Sambuc "{\n"
300*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
301*0a6a1f1dSLionel Sambuc " 'roots': [\n"
302*0a6a1f1dSLionel Sambuc " {\n"
303*0a6a1f1dSLionel Sambuc " 'type': 'directory',\n"
304*0a6a1f1dSLionel Sambuc " 'name': \"/\",\n"
305*0a6a1f1dSLionel Sambuc " 'contents': [\n"
306*0a6a1f1dSLionel Sambuc " {\n"
307*0a6a1f1dSLionel Sambuc " 'type': 'file',\n"
308*0a6a1f1dSLionel Sambuc " 'name': \"foo.h\",\n"
309*0a6a1f1dSLionel Sambuc " 'external-contents': \"/real/foo.h\"\n"
310*0a6a1f1dSLionel Sambuc " }\n"
311*0a6a1f1dSLionel Sambuc " ]\n"
312*0a6a1f1dSLionel Sambuc " }\n"
313*0a6a1f1dSLionel Sambuc " ]\n"
314*0a6a1f1dSLionel Sambuc "}\n";
315*0a6a1f1dSLionel Sambuc TestVFO T(contents);
316*0a6a1f1dSLionel Sambuc T.map("/foo.h", "/real/foo.h");
317*0a6a1f1dSLionel Sambuc }
318*0a6a1f1dSLionel Sambuc
TEST(libclang,VirtualFileOverlay_Empty)319*0a6a1f1dSLionel Sambuc TEST(libclang, VirtualFileOverlay_Empty) {
320*0a6a1f1dSLionel Sambuc const char *contents =
321*0a6a1f1dSLionel Sambuc "{\n"
322*0a6a1f1dSLionel Sambuc " 'version': 0,\n"
323*0a6a1f1dSLionel Sambuc " 'roots': [\n"
324*0a6a1f1dSLionel Sambuc " ]\n"
325*0a6a1f1dSLionel Sambuc "}\n";
326*0a6a1f1dSLionel Sambuc TestVFO T(contents);
327*0a6a1f1dSLionel Sambuc }
328*0a6a1f1dSLionel Sambuc
TEST(libclang,ModuleMapDescriptor)329*0a6a1f1dSLionel Sambuc TEST(libclang, ModuleMapDescriptor) {
330*0a6a1f1dSLionel Sambuc const char *Contents =
331*0a6a1f1dSLionel Sambuc "framework module TestFrame {\n"
332*0a6a1f1dSLionel Sambuc " umbrella header \"TestFrame.h\"\n"
333*0a6a1f1dSLionel Sambuc "\n"
334*0a6a1f1dSLionel Sambuc " export *\n"
335*0a6a1f1dSLionel Sambuc " module * { export * }\n"
336*0a6a1f1dSLionel Sambuc "}\n";
337*0a6a1f1dSLionel Sambuc
338*0a6a1f1dSLionel Sambuc CXModuleMapDescriptor MMD = clang_ModuleMapDescriptor_create(0);
339*0a6a1f1dSLionel Sambuc
340*0a6a1f1dSLionel Sambuc clang_ModuleMapDescriptor_setFrameworkModuleName(MMD, "TestFrame");
341*0a6a1f1dSLionel Sambuc clang_ModuleMapDescriptor_setUmbrellaHeader(MMD, "TestFrame.h");
342*0a6a1f1dSLionel Sambuc
343*0a6a1f1dSLionel Sambuc char *BufPtr;
344*0a6a1f1dSLionel Sambuc unsigned BufSize;
345*0a6a1f1dSLionel Sambuc clang_ModuleMapDescriptor_writeToBuffer(MMD, 0, &BufPtr, &BufSize);
346*0a6a1f1dSLionel Sambuc std::string BufStr(BufPtr, BufSize);
347*0a6a1f1dSLionel Sambuc EXPECT_STREQ(Contents, BufStr.c_str());
348*0a6a1f1dSLionel Sambuc free(BufPtr);
349*0a6a1f1dSLionel Sambuc clang_ModuleMapDescriptor_dispose(MMD);
350*0a6a1f1dSLionel Sambuc }
351*0a6a1f1dSLionel Sambuc
352*0a6a1f1dSLionel Sambuc class LibclangReparseTest : public ::testing::Test {
353*0a6a1f1dSLionel Sambuc std::set<std::string> Files;
354*0a6a1f1dSLionel Sambuc public:
355*0a6a1f1dSLionel Sambuc std::string TestDir;
356*0a6a1f1dSLionel Sambuc CXIndex Index;
357*0a6a1f1dSLionel Sambuc CXTranslationUnit ClangTU;
358*0a6a1f1dSLionel Sambuc unsigned TUFlags;
359*0a6a1f1dSLionel Sambuc
SetUp()360*0a6a1f1dSLionel Sambuc void SetUp() {
361*0a6a1f1dSLionel Sambuc llvm::SmallString<256> Dir;
362*0a6a1f1dSLionel Sambuc ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir));
363*0a6a1f1dSLionel Sambuc TestDir = Dir.str();
364*0a6a1f1dSLionel Sambuc TUFlags = CXTranslationUnit_DetailedPreprocessingRecord |
365*0a6a1f1dSLionel Sambuc clang_defaultEditingTranslationUnitOptions();
366*0a6a1f1dSLionel Sambuc Index = clang_createIndex(0, 0);
367*0a6a1f1dSLionel Sambuc }
TearDown()368*0a6a1f1dSLionel Sambuc void TearDown() {
369*0a6a1f1dSLionel Sambuc clang_disposeTranslationUnit(ClangTU);
370*0a6a1f1dSLionel Sambuc clang_disposeIndex(Index);
371*0a6a1f1dSLionel Sambuc for (const std::string &Path : Files)
372*0a6a1f1dSLionel Sambuc llvm::sys::fs::remove(Path);
373*0a6a1f1dSLionel Sambuc llvm::sys::fs::remove(TestDir);
374*0a6a1f1dSLionel Sambuc }
WriteFile(std::string & Filename,const std::string & Contents)375*0a6a1f1dSLionel Sambuc void WriteFile(std::string &Filename, const std::string &Contents) {
376*0a6a1f1dSLionel Sambuc if (!llvm::sys::path::is_absolute(Filename)) {
377*0a6a1f1dSLionel Sambuc llvm::SmallString<256> Path(TestDir);
378*0a6a1f1dSLionel Sambuc llvm::sys::path::append(Path, Filename);
379*0a6a1f1dSLionel Sambuc Filename = Path.str();
380*0a6a1f1dSLionel Sambuc Files.insert(Filename);
381*0a6a1f1dSLionel Sambuc }
382*0a6a1f1dSLionel Sambuc std::ofstream OS(Filename);
383*0a6a1f1dSLionel Sambuc OS << Contents;
384*0a6a1f1dSLionel Sambuc }
DisplayDiagnostics()385*0a6a1f1dSLionel Sambuc void DisplayDiagnostics() {
386*0a6a1f1dSLionel Sambuc unsigned NumDiagnostics = clang_getNumDiagnostics(ClangTU);
387*0a6a1f1dSLionel Sambuc for (unsigned i = 0; i < NumDiagnostics; ++i) {
388*0a6a1f1dSLionel Sambuc auto Diag = clang_getDiagnostic(ClangTU, i);
389*0a6a1f1dSLionel Sambuc DEBUG(llvm::dbgs() << clang_getCString(clang_formatDiagnostic(
390*0a6a1f1dSLionel Sambuc Diag, clang_defaultDiagnosticDisplayOptions())) << "\n");
391*0a6a1f1dSLionel Sambuc clang_disposeDiagnostic(Diag);
392*0a6a1f1dSLionel Sambuc }
393*0a6a1f1dSLionel Sambuc }
ReparseTU(unsigned num_unsaved_files,CXUnsavedFile * unsaved_files)394*0a6a1f1dSLionel Sambuc bool ReparseTU(unsigned num_unsaved_files, CXUnsavedFile* unsaved_files) {
395*0a6a1f1dSLionel Sambuc if (clang_reparseTranslationUnit(ClangTU, num_unsaved_files, unsaved_files,
396*0a6a1f1dSLionel Sambuc clang_defaultReparseOptions(ClangTU))) {
397*0a6a1f1dSLionel Sambuc DEBUG(llvm::dbgs() << "Reparse failed\n");
398*0a6a1f1dSLionel Sambuc return false;
399*0a6a1f1dSLionel Sambuc }
400*0a6a1f1dSLionel Sambuc DisplayDiagnostics();
401*0a6a1f1dSLionel Sambuc return true;
402*0a6a1f1dSLionel Sambuc }
403*0a6a1f1dSLionel Sambuc };
404*0a6a1f1dSLionel Sambuc
405*0a6a1f1dSLionel Sambuc
TEST_F(LibclangReparseTest,Reparse)406*0a6a1f1dSLionel Sambuc TEST_F(LibclangReparseTest, Reparse) {
407*0a6a1f1dSLionel Sambuc const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
408*0a6a1f1dSLionel Sambuc const char *HeaderBottom = "\n};\n#endif\n";
409*0a6a1f1dSLionel Sambuc const char *CppFile = "#include \"HeaderFile.h\"\nint main() {"
410*0a6a1f1dSLionel Sambuc " Foo foo; foo.bar = 7; foo.baz = 8; }\n";
411*0a6a1f1dSLionel Sambuc std::string HeaderName = "HeaderFile.h";
412*0a6a1f1dSLionel Sambuc std::string CppName = "CppFile.cpp";
413*0a6a1f1dSLionel Sambuc WriteFile(CppName, CppFile);
414*0a6a1f1dSLionel Sambuc WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
415*0a6a1f1dSLionel Sambuc
416*0a6a1f1dSLionel Sambuc ClangTU = clang_parseTranslationUnit(Index, CppName.c_str(), nullptr, 0,
417*0a6a1f1dSLionel Sambuc nullptr, 0, TUFlags);
418*0a6a1f1dSLionel Sambuc EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
419*0a6a1f1dSLionel Sambuc DisplayDiagnostics();
420*0a6a1f1dSLionel Sambuc
421*0a6a1f1dSLionel Sambuc // Immedaitely reparse.
422*0a6a1f1dSLionel Sambuc ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
423*0a6a1f1dSLionel Sambuc EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
424*0a6a1f1dSLionel Sambuc
425*0a6a1f1dSLionel Sambuc std::string NewHeaderContents =
426*0a6a1f1dSLionel Sambuc std::string(HeaderTop) + "int baz;" + HeaderBottom;
427*0a6a1f1dSLionel Sambuc WriteFile(HeaderName, NewHeaderContents);
428*0a6a1f1dSLionel Sambuc
429*0a6a1f1dSLionel Sambuc // Reparse after fix.
430*0a6a1f1dSLionel Sambuc ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
431*0a6a1f1dSLionel Sambuc EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
432*0a6a1f1dSLionel Sambuc }
433*0a6a1f1dSLionel Sambuc
TEST_F(LibclangReparseTest,ReparseWithModule)434*0a6a1f1dSLionel Sambuc TEST_F(LibclangReparseTest, ReparseWithModule) {
435*0a6a1f1dSLionel Sambuc const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
436*0a6a1f1dSLionel Sambuc const char *HeaderBottom = "\n};\n#endif\n";
437*0a6a1f1dSLionel Sambuc const char *MFile = "#include \"HeaderFile.h\"\nint main() {"
438*0a6a1f1dSLionel Sambuc " struct Foo foo; foo.bar = 7; foo.baz = 8; }\n";
439*0a6a1f1dSLionel Sambuc const char *ModFile = "module A { header \"HeaderFile.h\" }\n";
440*0a6a1f1dSLionel Sambuc std::string HeaderName = "HeaderFile.h";
441*0a6a1f1dSLionel Sambuc std::string MName = "MFile.m";
442*0a6a1f1dSLionel Sambuc std::string ModName = "module.modulemap";
443*0a6a1f1dSLionel Sambuc WriteFile(MName, MFile);
444*0a6a1f1dSLionel Sambuc WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
445*0a6a1f1dSLionel Sambuc WriteFile(ModName, ModFile);
446*0a6a1f1dSLionel Sambuc
447*0a6a1f1dSLionel Sambuc std::string ModulesCache = std::string("-fmodules-cache-path=") + TestDir;
448*0a6a1f1dSLionel Sambuc const char *Args[] = { "-fmodules", ModulesCache.c_str(),
449*0a6a1f1dSLionel Sambuc "-I", TestDir.c_str() };
450*0a6a1f1dSLionel Sambuc int NumArgs = sizeof(Args) / sizeof(Args[0]);
451*0a6a1f1dSLionel Sambuc ClangTU = clang_parseTranslationUnit(Index, MName.c_str(), Args, NumArgs,
452*0a6a1f1dSLionel Sambuc nullptr, 0, TUFlags);
453*0a6a1f1dSLionel Sambuc EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
454*0a6a1f1dSLionel Sambuc DisplayDiagnostics();
455*0a6a1f1dSLionel Sambuc
456*0a6a1f1dSLionel Sambuc // Immedaitely reparse.
457*0a6a1f1dSLionel Sambuc ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
458*0a6a1f1dSLionel Sambuc EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
459*0a6a1f1dSLionel Sambuc
460*0a6a1f1dSLionel Sambuc std::string NewHeaderContents =
461*0a6a1f1dSLionel Sambuc std::string(HeaderTop) + "int baz;" + HeaderBottom;
462*0a6a1f1dSLionel Sambuc WriteFile(HeaderName, NewHeaderContents);
463*0a6a1f1dSLionel Sambuc
464*0a6a1f1dSLionel Sambuc // Reparse after fix.
465*0a6a1f1dSLionel Sambuc ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
466*0a6a1f1dSLionel Sambuc EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
467*0a6a1f1dSLionel Sambuc }
468