1 //===- unittests/Lex/HeaderSearchTest.cpp ------ HeaderSearch tests -------===// 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/Lex/HeaderSearch.h" 10 #include "clang/Basic/Diagnostic.h" 11 #include "clang/Basic/DiagnosticOptions.h" 12 #include "clang/Basic/FileManager.h" 13 #include "clang/Basic/LangOptions.h" 14 #include "clang/Basic/SourceManager.h" 15 #include "clang/Basic/TargetInfo.h" 16 #include "clang/Basic/TargetOptions.h" 17 #include "clang/Lex/HeaderSearch.h" 18 #include "clang/Lex/HeaderSearchOptions.h" 19 #include "clang/Serialization/InMemoryModuleCache.h" 20 #include "gtest/gtest.h" 21 22 namespace clang { 23 namespace { 24 25 // The test fixture. 26 class HeaderSearchTest : public ::testing::Test { 27 protected: 28 HeaderSearchTest() 29 : VFS(new llvm::vfs::InMemoryFileSystem), FileMgr(FileMgrOpts, VFS), 30 DiagID(new DiagnosticIDs()), 31 Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()), 32 SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions), 33 Search(std::make_shared<HeaderSearchOptions>(), SourceMgr, Diags, 34 LangOpts, Target.get()) { 35 TargetOpts->Triple = "x86_64-apple-darwin11.1.0"; 36 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 37 } 38 39 void addSearchDir(llvm::StringRef Dir) { 40 VFS->addFile(Dir, 0, llvm::MemoryBuffer::getMemBuffer(""), /*User=*/None, 41 /*Group=*/None, llvm::sys::fs::file_type::directory_file); 42 auto DE = FileMgr.getDirectory(Dir); 43 assert(DE); 44 auto DL = DirectoryLookup(*DE, SrcMgr::C_User, /*isFramework=*/false); 45 Search.AddSearchPath(DL, /*isAngled=*/false); 46 } 47 48 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS; 49 FileSystemOptions FileMgrOpts; 50 FileManager FileMgr; 51 IntrusiveRefCntPtr<DiagnosticIDs> DiagID; 52 DiagnosticsEngine Diags; 53 SourceManager SourceMgr; 54 LangOptions LangOpts; 55 std::shared_ptr<TargetOptions> TargetOpts; 56 IntrusiveRefCntPtr<TargetInfo> Target; 57 HeaderSearch Search; 58 }; 59 60 TEST_F(HeaderSearchTest, NoSearchDir) { 61 EXPECT_EQ(Search.search_dir_size(), 0u); 62 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/z", /*WorkingDir=*/"", 63 /*MainFile=*/""), 64 "/x/y/z"); 65 } 66 67 TEST_F(HeaderSearchTest, SimpleShorten) { 68 addSearchDir("/x"); 69 addSearchDir("/x/y"); 70 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/z", /*WorkingDir=*/"", 71 /*MainFile=*/""), 72 "z"); 73 addSearchDir("/a/b/"); 74 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/a/b/c", /*WorkingDir=*/"", 75 /*MainFile=*/""), 76 "c"); 77 } 78 79 TEST_F(HeaderSearchTest, ShortenWithWorkingDir) { 80 addSearchDir("x/y"); 81 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/a/b/c/x/y/z", 82 /*WorkingDir=*/"/a/b/c", 83 /*MainFile=*/""), 84 "z"); 85 } 86 87 TEST_F(HeaderSearchTest, Dots) { 88 addSearchDir("/x/./y/"); 89 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/./z", 90 /*WorkingDir=*/"", 91 /*MainFile=*/""), 92 "z"); 93 addSearchDir("a/.././c/"); 94 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/m/n/./c/z", 95 /*WorkingDir=*/"/m/n/", 96 /*MainFile=*/""), 97 "z"); 98 } 99 100 #ifdef _WIN32 101 TEST_F(HeaderSearchTest, BackSlash) { 102 addSearchDir("C:\\x\\y\\"); 103 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("C:\\x\\y\\z\\t", 104 /*WorkingDir=*/"", 105 /*MainFile=*/""), 106 "z/t"); 107 } 108 109 TEST_F(HeaderSearchTest, BackSlashWithDotDot) { 110 addSearchDir("..\\y"); 111 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("C:\\x\\y\\z\\t", 112 /*WorkingDir=*/"C:/x/y/", 113 /*MainFile=*/""), 114 "z/t"); 115 } 116 #endif 117 118 TEST_F(HeaderSearchTest, DotDotsWithAbsPath) { 119 addSearchDir("/x/../y/"); 120 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/y/z", 121 /*WorkingDir=*/"", 122 /*MainFile=*/""), 123 "z"); 124 } 125 126 TEST_F(HeaderSearchTest, IncludeFromSameDirectory) { 127 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/y/z/t.h", 128 /*WorkingDir=*/"", 129 /*MainFile=*/"/y/a.cc"), 130 "z/t.h"); 131 132 addSearchDir("/"); 133 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/y/z/t.h", 134 /*WorkingDir=*/"", 135 /*MainFile=*/"/y/a.cc"), 136 "y/z/t.h"); 137 } 138 139 } // namespace 140 } // namespace clang 141