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 const DirectoryEntry *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 "/x/y/z"); 64 } 65 66 TEST_F(HeaderSearchTest, SimpleShorten) { 67 addSearchDir("/x"); 68 addSearchDir("/x/y"); 69 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/z", /*WorkingDir=*/""), 70 "z"); 71 addSearchDir("/a/b/"); 72 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/a/b/c", /*WorkingDir=*/""), 73 "c"); 74 } 75 76 TEST_F(HeaderSearchTest, ShortenWithWorkingDir) { 77 addSearchDir("x/y"); 78 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/a/b/c/x/y/z", 79 /*WorkingDir=*/"/a/b/c"), 80 "z"); 81 } 82 83 TEST_F(HeaderSearchTest, Dots) { 84 addSearchDir("/x/./y/"); 85 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/./z", 86 /*WorkingDir=*/""), 87 "z"); 88 addSearchDir("a/.././c/"); 89 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/m/n/./c/z", 90 /*WorkingDir=*/"/m/n/"), 91 "z"); 92 } 93 94 #ifdef _WIN32 95 TEST_F(HeaderSearchTest, BackSlash) { 96 addSearchDir("C:\\x\\y\\"); 97 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("C:\\x\\y\\z\\t", 98 /*WorkingDir=*/""), 99 "z/t"); 100 } 101 102 TEST_F(HeaderSearchTest, BackSlashWithDotDot) { 103 addSearchDir("..\\y"); 104 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("C:\\x\\y\\z\\t", 105 /*WorkingDir=*/"C:/x/y/"), 106 "z/t"); 107 } 108 #endif 109 110 TEST_F(HeaderSearchTest, DotDotsWithAbsPath) { 111 addSearchDir("/x/../y/"); 112 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/y/z", 113 /*WorkingDir=*/""), 114 "z"); 115 } 116 117 } // namespace 118 } // namespace clang 119