summaryrefslogtreecommitdiff
path: root/unittests/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Lex')
-rw-r--r--unittests/Lex/CMakeLists.txt1
-rw-r--r--unittests/Lex/HeaderSearchTest.cpp96
-rw-r--r--unittests/Lex/LexerTest.cpp14
-rw-r--r--unittests/Lex/PPCallbacksTest.cpp58
4 files changed, 151 insertions, 18 deletions
diff --git a/unittests/Lex/CMakeLists.txt b/unittests/Lex/CMakeLists.txt
index ea6f9fd234020..bb0f66d860734 100644
--- a/unittests/Lex/CMakeLists.txt
+++ b/unittests/Lex/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
add_clang_unittest(LexTests
HeaderMapTest.cpp
+ HeaderSearchTest.cpp
LexerTest.cpp
PPCallbacksTest.cpp
PPConditionalDirectiveRecordTest.cpp
diff --git a/unittests/Lex/HeaderSearchTest.cpp b/unittests/Lex/HeaderSearchTest.cpp
new file mode 100644
index 0000000000000..c2794f5e95939
--- /dev/null
+++ b/unittests/Lex/HeaderSearchTest.cpp
@@ -0,0 +1,96 @@
+//===- unittests/Lex/HeaderSearchTest.cpp ------ HeaderSearch tests -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace {
+
+// The test fixture.
+class HeaderSearchTest : public ::testing::Test {
+protected:
+ HeaderSearchTest()
+ : VFS(new vfs::InMemoryFileSystem), FileMgr(FileMgrOpts, VFS),
+ DiagID(new DiagnosticIDs()),
+ Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+ SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions),
+ Search(std::make_shared<HeaderSearchOptions>(), SourceMgr, Diags,
+ LangOpts, Target.get()) {
+ TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
+ Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ }
+
+ void addSearchDir(llvm::StringRef Dir) {
+ VFS->addFile(Dir, 0, llvm::MemoryBuffer::getMemBuffer(""), /*User=*/None,
+ /*Group=*/None, llvm::sys::fs::file_type::directory_file);
+ const DirectoryEntry *DE = FileMgr.getDirectory(Dir);
+ assert(DE);
+ auto DL = DirectoryLookup(DE, SrcMgr::C_User, /*isFramework=*/false);
+ Search.AddSearchPath(DL, /*isAngled=*/false);
+ }
+
+ IntrusiveRefCntPtr<vfs::InMemoryFileSystem> VFS;
+ FileSystemOptions FileMgrOpts;
+ FileManager FileMgr;
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+ DiagnosticsEngine Diags;
+ SourceManager SourceMgr;
+ LangOptions LangOpts;
+ std::shared_ptr<TargetOptions> TargetOpts;
+ IntrusiveRefCntPtr<TargetInfo> Target;
+ HeaderSearch Search;
+};
+
+TEST_F(HeaderSearchTest, NoSearchDir) {
+ EXPECT_EQ(Search.search_dir_size(), 0u);
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/z", /*WorkingDir=*/""),
+ "/x/y/z");
+}
+
+TEST_F(HeaderSearchTest, SimpleShorten) {
+ addSearchDir("/x");
+ addSearchDir("/x/y");
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/z", /*WorkingDir=*/""),
+ "z");
+ addSearchDir("/a/b/");
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/a/b/c", /*WorkingDir=*/""),
+ "c");
+}
+
+TEST_F(HeaderSearchTest, ShortenWithWorkingDir) {
+ addSearchDir("x/y");
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/a/b/c/x/y/z",
+ /*WorkingDir=*/"/a/b/c"),
+ "z");
+}
+
+TEST_F(HeaderSearchTest, Dots) {
+ addSearchDir("/x/./y/");
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/x/y/./z",
+ /*WorkingDir=*/""),
+ "z");
+ addSearchDir("a/.././c/");
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/m/n/./c/z",
+ /*WorkingDir=*/"/m/n/"),
+ "z");
+}
+
+} // namespace
+} // namespace clang
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index d699a44b13fdb..c913062a7abf6 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -286,9 +286,7 @@ TEST_F(LexerTest, LexAPI) {
SourceLocation lsqrLoc = toks[0].getLocation();
SourceLocation idLoc = toks[1].getLocation();
SourceLocation rsqrLoc = toks[2].getLocation();
- std::pair<SourceLocation,SourceLocation>
- macroPair = SourceMgr.getExpansionRange(lsqrLoc);
- SourceRange macroRange = SourceRange(macroPair.first, macroPair.second);
+ CharSourceRange macroRange = SourceMgr.getExpansionRange(lsqrLoc);
SourceLocation Loc;
EXPECT_TRUE(Lexer::isAtStartOfMacroExpansion(lsqrLoc, SourceMgr, LangOpts, &Loc));
@@ -297,6 +295,7 @@ TEST_F(LexerTest, LexAPI) {
EXPECT_FALSE(Lexer::isAtEndOfMacroExpansion(idLoc, SourceMgr, LangOpts));
EXPECT_TRUE(Lexer::isAtEndOfMacroExpansion(rsqrLoc, SourceMgr, LangOpts, &Loc));
EXPECT_EQ(Loc, macroRange.getEnd());
+ EXPECT_TRUE(macroRange.isTokenRange());
CharSourceRange range = Lexer::makeFileCharRange(
CharSourceRange::getTokenRange(lsqrLoc, idLoc), SourceMgr, LangOpts);
@@ -334,11 +333,11 @@ TEST_F(LexerTest, LexAPI) {
EXPECT_EQ(SourceRange(fileIdLoc, fileRsqrLoc.getLocWithOffset(1)),
range.getAsRange());
- macroPair = SourceMgr.getExpansionRange(macroLsqrLoc);
+ macroRange = SourceMgr.getExpansionRange(macroLsqrLoc);
range = Lexer::makeFileCharRange(
CharSourceRange::getTokenRange(macroLsqrLoc, macroRsqrLoc),
SourceMgr, LangOpts);
- EXPECT_EQ(SourceRange(macroPair.first, macroPair.second.getLocWithOffset(1)),
+ EXPECT_EQ(SourceRange(macroRange.getBegin(), macroRange.getEnd().getLocWithOffset(1)),
range.getAsRange());
text = Lexer::getSourceText(
@@ -474,8 +473,9 @@ TEST_F(LexerTest, GetBeginningOfTokenWithEscapedNewLine) {
}
TEST_F(LexerTest, AvoidPastEndOfStringDereference) {
- std::vector<Token> LexedTokens = Lex(" // \\\n");
- EXPECT_TRUE(LexedTokens.empty());
+ EXPECT_TRUE(Lex(" // \\\n").empty());
+ EXPECT_TRUE(Lex("#include <\\\\").empty());
+ EXPECT_TRUE(Lex("#include <\\\\\n").empty());
}
TEST_F(LexerTest, StringizingRasString) {
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index 67b56a601c71a..0fa6286cc0480 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -39,16 +39,18 @@ public:
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override {
- this->HashLoc = HashLoc;
- this->IncludeTok = IncludeTok;
- this->FileName = FileName.str();
- this->IsAngled = IsAngled;
- this->FilenameRange = FilenameRange;
- this->File = File;
- this->SearchPath = SearchPath.str();
- this->RelativePath = RelativePath.str();
- this->Imported = Imported;
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override {
+ this->HashLoc = HashLoc;
+ this->IncludeTok = IncludeTok;
+ this->FileName = FileName.str();
+ this->IsAngled = IsAngled;
+ this->FilenameRange = FilenameRange;
+ this->File = File;
+ this->SearchPath = SearchPath.str();
+ this->RelativePath = RelativePath.str();
+ this->Imported = Imported;
+ this->FileType = FileType;
}
SourceLocation HashLoc;
@@ -60,6 +62,7 @@ public:
SmallString<16> SearchPath;
SmallString<16> RelativePath;
const Module* Imported;
+ SrcMgr::CharacteristicKind FileType;
};
// Stub to collect data from PragmaOpenCLExtension callbacks.
@@ -153,6 +156,30 @@ protected:
SourceMgr, PCMCache, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
+ return InclusionDirectiveCallback(PP)->FilenameRange;
+ }
+
+ SrcMgr::CharacteristicKind InclusionDirectiveCharacteristicKind(
+ const char *SourceText, const char *HeaderPath, bool SystemHeader) {
+ std::unique_ptr<llvm::MemoryBuffer> Buf =
+ llvm::MemoryBuffer::getMemBuffer(SourceText);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
+
+ TrivialModuleLoader ModLoader;
+ MemoryBufferCache PCMCache;
+
+ HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+ Diags, LangOpts, Target.get());
+ AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
+
+ Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+ SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ /*IILookup =*/nullptr,
+ /*OwnsHeaderSearch =*/false);
+ return InclusionDirectiveCallback(PP)->FileType;
+ }
+
+ InclusionDirectiveCallbacks *InclusionDirectiveCallback(Preprocessor &PP) {
PP.Initialize(*Target);
InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks;
PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
@@ -168,7 +195,7 @@ protected:
}
// Callbacks have been executed at this point -- return filename range.
- return Callbacks->FilenameRange;
+ return Callbacks;
}
PragmaOpenCLExtensionCallbacks::CallbackParameters
@@ -222,6 +249,15 @@ protected:
}
};
+TEST_F(PPCallbacksTest, UserFileCharacteristics) {
+ const char *Source = "#include \"quoted.h\"\n";
+
+ SrcMgr::CharacteristicKind Kind =
+ InclusionDirectiveCharacteristicKind(Source, "/quoted.h", false);
+
+ ASSERT_EQ(SrcMgr::CharacteristicKind::C_User, Kind);
+}
+
TEST_F(PPCallbacksTest, QuotedFilename) {
const char* Source =
"#include \"quoted.h\"\n";