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:
HeaderSearchTest()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
addSearchDir(llvm::StringRef Dir)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.getOptionalDirectoryRef(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
TEST_F(HeaderSearchTest,NoSearchDir)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
TEST_F(HeaderSearchTest,SimpleShorten)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
TEST_F(HeaderSearchTest,ShortenWithWorkingDir)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
TEST_F(HeaderSearchTest,Dots)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
TEST_F(HeaderSearchTest,BackSlash)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
TEST_F(HeaderSearchTest,BackSlashWithDotDot)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
TEST_F(HeaderSearchTest,DotDotsWithAbsPath)118 TEST_F(HeaderSearchTest, DotDotsWithAbsPath) {
119 addSearchDir("/x/../y/");
120 EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/y/z",
121 /*WorkingDir=*/"",
122 /*MainFile=*/""),
123 "z");
124 }
125
TEST_F(HeaderSearchTest,IncludeFromSameDirectory)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