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