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 184 TEST(DirectoryEntryTest, isSameRef) { 185 FileEntryTestHelper Refs; 186 DirectoryEntryRef R1 = Refs.addDirectory("1"); 187 DirectoryEntryRef R2 = Refs.addDirectory("2"); 188 DirectoryEntryRef R1Also = Refs.addDirectoryAlias("1-also", R1); 189 190 EXPECT_TRUE(R1.isSameRef(DirectoryEntryRef(R1))); 191 EXPECT_TRUE(R1.isSameRef(DirectoryEntryRef(R1.getMapEntry()))); 192 EXPECT_FALSE(R1.isSameRef(R2)); 193 EXPECT_FALSE(R1.isSameRef(R1Also)); 194 } 195 196 TEST(DirectoryEntryTest, DenseMapInfo) { 197 FileEntryTestHelper Refs; 198 DirectoryEntryRef R1 = Refs.addDirectory("1"); 199 DirectoryEntryRef R2 = Refs.addDirectory("2"); 200 DirectoryEntryRef R1Also = Refs.addDirectoryAlias("1-also", R1); 201 202 // Insert R1Also first and confirm it "wins". 203 { 204 SmallDenseSet<DirectoryEntryRef, 8> Set; 205 Set.insert(R1Also); 206 Set.insert(R1); 207 Set.insert(R2); 208 EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1Also)); 209 EXPECT_TRUE(Set.find(R1)->isSameRef(R1Also)); 210 EXPECT_TRUE(Set.find(R2)->isSameRef(R2)); 211 } 212 213 // Insert R1Also second and confirm R1 "wins". 214 { 215 SmallDenseSet<DirectoryEntryRef, 8> Set; 216 Set.insert(R1); 217 Set.insert(R1Also); 218 Set.insert(R2); 219 EXPECT_TRUE(Set.find(R1Also)->isSameRef(R1)); 220 EXPECT_TRUE(Set.find(R1)->isSameRef(R1)); 221 EXPECT_TRUE(Set.find(R2)->isSameRef(R2)); 222 } 223 } 224 225 } // end namespace 226 } // namespace clang 227