xref: /llvm-project/clang/unittests/Basic/FileEntryTest.cpp (revision 8a2fb1391bbf8e432b5e1cf1ae8b870446371031)
1 //===- unittests/Basic/FileEntryTest.cpp - Test FileEntry/FileEntryRef ----===//
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 #include "clang/Basic/FileEntry.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/StringMap.h"
12 #include "llvm/Support/Path.h"
13 #include "gtest/gtest.h"
14 
15 using namespace llvm;
16 
17 namespace clang {
18 
19 class FileEntryTestHelper {
20   StringMap<llvm::ErrorOr<FileEntryRef::MapValue>> Files;
21   StringMap<llvm::ErrorOr<DirectoryEntry &>> Dirs;
22 
23   SmallVector<std::unique_ptr<FileEntry>, 5> FEs;
24   SmallVector<std::unique_ptr<DirectoryEntry>, 5> DEs;
25   DirectoryEntryRef DR;
26 
27 public:
28   FileEntryTestHelper() : DR(addDirectory("dir")) {}
29 
30   DirectoryEntryRef addDirectory(StringRef Name) {
31     DEs.emplace_back(new DirectoryEntry());
32     return DirectoryEntryRef(*Dirs.insert({Name, *DEs.back()}).first);
33   }
34   DirectoryEntryRef addDirectoryAlias(StringRef Name, DirectoryEntryRef Base) {
35     return DirectoryEntryRef(
36         *Dirs.insert({Name, const_cast<DirectoryEntry &>(Base.getDirEntry())})
37              .first);
38   }
39 
40   FileEntryRef addFile(StringRef Name) {
41     FEs.emplace_back(new FileEntry());
42     return FileEntryRef(
43         *Files.insert({Name, FileEntryRef::MapValue(*FEs.back().get(), DR)})
44              .first);
45   }
46   FileEntryRef addFileAlias(StringRef Name, FileEntryRef Base) {
47     return FileEntryRef(
48         *Files
49              .insert(
50                  {Name, FileEntryRef::MapValue(
51                             const_cast<FileEntry &>(Base.getFileEntry()), DR)})
52              .first);
53   }
54   FileEntryRef addFileRedirect(StringRef Name, FileEntryRef Base) {
55     auto Dir = addDirectory(llvm::sys::path::parent_path(Name));
56 
57     return FileEntryRef(
58         *Files
59              .insert({Name, FileEntryRef::MapValue(
60                                 const_cast<FileEntryRef::MapEntry &>(
61                                     Base.getMapEntry()),
62                                 Dir)})
63              .first);
64   }
65 };
66 
67 namespace {
68 TEST(FileEntryTest, FileEntryRef) {
69   FileEntryTestHelper Refs;
70   FileEntryRef R1 = Refs.addFile("1");
71   FileEntryRef R2 = Refs.addFile("2");
72   FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);
73   FileEntryRef R1Redirect = Refs.addFileRedirect("1-redirect", R1);
74   FileEntryRef R1Redirect2 = Refs.addFileRedirect("1-redirect2", R1Redirect);
75 
76   EXPECT_EQ("1", R1.getName());
77   EXPECT_EQ("2", R2.getName());
78   EXPECT_EQ("1-also", R1Also.getName());
79   EXPECT_EQ("1", R1Redirect.getName());
80   EXPECT_EQ("1", R1Redirect2.getName());
81 
82   EXPECT_EQ("1", R1.getNameAsRequested());
83   EXPECT_EQ("1-redirect", R1Redirect.getNameAsRequested());
84   EXPECT_EQ("1-redirect2", R1Redirect2.getNameAsRequested());
85 
86   EXPECT_NE(&R1.getFileEntry(), &R2.getFileEntry());
87   EXPECT_EQ(&R1.getFileEntry(), &R1Also.getFileEntry());
88   EXPECT_EQ(&R1.getFileEntry(), &R1Redirect.getFileEntry());
89   EXPECT_EQ(&R1Redirect.getFileEntry(), &R1Redirect2.getFileEntry());
90 
91   const FileEntry *CE1 = R1;
92   EXPECT_EQ(CE1, &R1.getFileEntry());
93 }
94 
95 TEST(FileEntryTest, OptionalFileEntryRefDegradesToFileEntryPtr) {
96   FileEntryTestHelper Refs;
97   OptionalFileEntryRefDegradesToFileEntryPtr M0;
98   OptionalFileEntryRefDegradesToFileEntryPtr M1 = Refs.addFile("1");
99   OptionalFileEntryRefDegradesToFileEntryPtr M2 = Refs.addFile("2");
100   OptionalFileEntryRefDegradesToFileEntryPtr M0Also = std::nullopt;
101   OptionalFileEntryRefDegradesToFileEntryPtr M1Also =
102       Refs.addFileAlias("1-also", *M1);
103 
104   EXPECT_EQ(M0, M0Also);
105   EXPECT_EQ(StringRef("1"), M1->getName());
106   EXPECT_EQ(StringRef("2"), M2->getName());
107   EXPECT_EQ(StringRef("1-also"), M1Also->getName());
108 
109   const FileEntry *CE1 = M1;
110   EXPECT_EQ(CE1, &M1->getFileEntry());
111 }
112 
113 TEST(FileEntryTest, equals) {
114   FileEntryTestHelper Refs;
115   FileEntryRef R1 = Refs.addFile("1");
116   FileEntryRef R2 = Refs.addFile("2");
117   FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);
118   FileEntryRef R1Redirect = Refs.addFileRedirect("1-redirect", R1);
119   FileEntryRef R1Redirect2 = Refs.addFileRedirect("1-redirect2", R1Redirect);
120 
121   EXPECT_EQ(R1, &R1.getFileEntry());
122   EXPECT_EQ(&R1.getFileEntry(), R1);
123   EXPECT_EQ(R1, R1Also);
124   EXPECT_NE(R1, &R2.getFileEntry());
125   EXPECT_NE(&R2.getFileEntry(), R1);
126   EXPECT_NE(R1, R2);
127   EXPECT_EQ(R1, R1Redirect);
128   EXPECT_EQ(R1, R1Redirect2);
129 
130   OptionalFileEntryRefDegradesToFileEntryPtr M1 = R1;
131 
132   EXPECT_EQ(M1, &R1.getFileEntry());
133   EXPECT_EQ(&R1.getFileEntry(), M1);
134   EXPECT_NE(M1, &R2.getFileEntry());
135   EXPECT_NE(&R2.getFileEntry(), M1);
136 }
137 
138 TEST(FileEntryTest, isSameRef) {
139   FileEntryTestHelper Refs;
140   FileEntryRef R1 = Refs.addFile("1");
141   FileEntryRef R2 = Refs.addFile("2");
142   FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);
143   FileEntryRef R1Redirect = Refs.addFileRedirect("1-redirect", R1);
144   FileEntryRef R1Redirect2 = Refs.addFileRedirect("1-redirect2", R1Redirect);
145 
146   EXPECT_TRUE(R1.isSameRef(FileEntryRef(R1)));
147   EXPECT_TRUE(R1.isSameRef(FileEntryRef(R1.getMapEntry())));
148   EXPECT_FALSE(R1.isSameRef(R2));
149   EXPECT_FALSE(R1.isSameRef(R1Also));
150   EXPECT_FALSE(R1.isSameRef(R1Redirect));
151   EXPECT_FALSE(R1.isSameRef(R1Redirect2));
152   EXPECT_FALSE(R1Redirect.isSameRef(R1Redirect2));
153 }
154 
155 TEST(FileEntryTest, DenseMapInfo) {
156   FileEntryTestHelper Refs;
157   FileEntryRef R1 = Refs.addFile("1");
158   FileEntryRef R2 = Refs.addFile("2");
159   FileEntryRef R1Also = Refs.addFileAlias("1-also", R1);
160 
161   // Insert R1Also first and confirm it "wins".
162   {
163     SmallDenseSet<FileEntryRef, 8> Set;
164     Set.insert(R1Also);
165     Set.insert(R1);
166     Set.insert(R2);
167     EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1Also));
168     EXPECT_TRUE(Set.find(R1)->isSameRef(R1Also));
169     EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
170   }
171 
172   // Insert R1Also second and confirm R1 "wins".
173   {
174     SmallDenseSet<FileEntryRef, 8> Set;
175     Set.insert(R1);
176     Set.insert(R1Also);
177     Set.insert(R2);
178     EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1));
179     EXPECT_TRUE(Set.find(R1)->isSameRef(R1));
180     EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
181   }
182 
183   // Insert R1Also first and confirm it "wins" when looked up as FileEntry.
184   {
185     SmallDenseSet<FileEntryRef, 8> Set;
186     Set.insert(R1Also);
187     Set.insert(R1);
188     Set.insert(R2);
189 
190     auto R1AlsoIt = Set.find_as(&R1Also.getFileEntry());
191     ASSERT_TRUE(R1AlsoIt != Set.end());
192     EXPECT_TRUE(R1AlsoIt->isSameRef(R1Also));
193 
194     auto R1It = Set.find_as(&R1.getFileEntry());
195     ASSERT_TRUE(R1It != Set.end());
196     EXPECT_TRUE(R1It->isSameRef(R1Also));
197 
198     auto R2It = Set.find_as(&R2.getFileEntry());
199     ASSERT_TRUE(R2It != Set.end());
200     EXPECT_TRUE(R2It->isSameRef(R2));
201   }
202 
203   // Insert R1Also second and confirm R1 "wins" when looked up as FileEntry.
204   {
205     SmallDenseSet<FileEntryRef, 8> Set;
206     Set.insert(R1);
207     Set.insert(R1Also);
208     Set.insert(R2);
209 
210     auto R1AlsoIt = Set.find_as(&R1Also.getFileEntry());
211     ASSERT_TRUE(R1AlsoIt != Set.end());
212     EXPECT_TRUE(R1AlsoIt->isSameRef(R1));
213 
214     auto R1It = Set.find_as(&R1.getFileEntry());
215     ASSERT_TRUE(R1It != Set.end());
216     EXPECT_TRUE(R1It->isSameRef(R1));
217 
218     auto R2It = Set.find_as(&R2.getFileEntry());
219     ASSERT_TRUE(R2It != Set.end());
220     EXPECT_TRUE(R2It->isSameRef(R2));
221   }
222 }
223 
224 TEST(DirectoryEntryTest, isSameRef) {
225   FileEntryTestHelper Refs;
226   DirectoryEntryRef R1 = Refs.addDirectory("1");
227   DirectoryEntryRef R2 = Refs.addDirectory("2");
228   DirectoryEntryRef R1Also = Refs.addDirectoryAlias("1-also", R1);
229 
230   EXPECT_TRUE(R1.isSameRef(DirectoryEntryRef(R1)));
231   EXPECT_TRUE(R1.isSameRef(DirectoryEntryRef(R1.getMapEntry())));
232   EXPECT_FALSE(R1.isSameRef(R2));
233   EXPECT_FALSE(R1.isSameRef(R1Also));
234 }
235 
236 TEST(DirectoryEntryTest, DenseMapInfo) {
237   FileEntryTestHelper Refs;
238   DirectoryEntryRef R1 = Refs.addDirectory("1");
239   DirectoryEntryRef R2 = Refs.addDirectory("2");
240   DirectoryEntryRef R1Also = Refs.addDirectoryAlias("1-also", R1);
241 
242   // Insert R1Also first and confirm it "wins".
243   {
244     SmallDenseSet<DirectoryEntryRef, 8> Set;
245     Set.insert(R1Also);
246     Set.insert(R1);
247     Set.insert(R2);
248     EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1Also));
249     EXPECT_TRUE(Set.find(R1)->isSameRef(R1Also));
250     EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
251   }
252 
253   // Insert R1Also second and confirm R1 "wins".
254   {
255     SmallDenseSet<DirectoryEntryRef, 8> Set;
256     Set.insert(R1);
257     Set.insert(R1Also);
258     Set.insert(R2);
259     EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1));
260     EXPECT_TRUE(Set.find(R1)->isSameRef(R1));
261     EXPECT_TRUE(Set.find(R2)->isSameRef(R2));
262   }
263 }
264 
265 } // end namespace
266 } // namespace clang
267