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