summaryrefslogtreecommitdiff
path: root/unittests/Lex/PPCallbacksTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Lex/PPCallbacksTest.cpp')
-rw-r--r--unittests/Lex/PPCallbacksTest.cpp119
1 files changed, 97 insertions, 22 deletions
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index 0fa6286cc0480..838e033e3df49 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -65,6 +65,29 @@ public:
SrcMgr::CharacteristicKind FileType;
};
+class CondDirectiveCallbacks : public PPCallbacks {
+public:
+ struct Result {
+ SourceRange ConditionRange;
+ ConditionValueKind ConditionValue;
+
+ Result(SourceRange R, ConditionValueKind K)
+ : ConditionRange(R), ConditionValue(K) {}
+ };
+
+ std::vector<Result> Results;
+
+ void If(SourceLocation Loc, SourceRange ConditionRange,
+ ConditionValueKind ConditionValue) override {
+ Results.emplace_back(ConditionRange, ConditionValue);
+ }
+
+ void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
+ Results.emplace_back(ConditionRange, ConditionValue);
+ }
+};
+
// Stub to collect data from PragmaOpenCLExtension callbacks.
class PragmaOpenCLExtensionCallbacks : public PPCallbacks {
public:
@@ -95,7 +118,7 @@ public:
class PPCallbacksTest : public ::testing::Test {
protected:
PPCallbacksTest()
- : InMemoryFileSystem(new vfs::InMemoryFileSystem),
+ : InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
FileMgr(FileSystemOptions(), InMemoryFileSystem),
DiagID(new DiagnosticIDs()), DiagOpts(new DiagnosticOptions()),
Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
@@ -104,7 +127,7 @@ protected:
Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
}
- IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
FileManager FileMgr;
IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
@@ -116,17 +139,17 @@ protected:
// Register a header path as a known file and add its location
// to search path.
- void AddFakeHeader(HeaderSearch& HeaderInfo, const char* HeaderPath,
- bool IsSystemHeader) {
- // Tell FileMgr about header.
- InMemoryFileSystem->addFile(HeaderPath, 0,
- llvm::MemoryBuffer::getMemBuffer("\n"));
-
- // Add header's parent path to search path.
- StringRef SearchPath = llvm::sys::path::parent_path(HeaderPath);
- const DirectoryEntry *DE = FileMgr.getDirectory(SearchPath);
- DirectoryLookup DL(DE, SrcMgr::C_User, false);
- HeaderInfo.AddSearchPath(DL, IsSystemHeader);
+ void AddFakeHeader(HeaderSearch &HeaderInfo, const char *HeaderPath,
+ bool IsSystemHeader) {
+ // Tell FileMgr about header.
+ InMemoryFileSystem->addFile(HeaderPath, 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+
+ // Add header's parent path to search path.
+ StringRef SearchPath = llvm::sys::path::parent_path(HeaderPath);
+ const DirectoryEntry *DE = FileMgr.getDirectory(SearchPath);
+ DirectoryLookup DL(DE, SrcMgr::C_User, false);
+ HeaderInfo.AddSearchPath(DL, IsSystemHeader);
}
// Get the raw source string of the range.
@@ -137,10 +160,20 @@ protected:
return StringRef(B, E - B);
}
+ StringRef GetSourceStringToEnd(CharSourceRange Range) {
+ const char *B = SourceMgr.getCharacterData(Range.getBegin());
+ const char *E = SourceMgr.getCharacterData(Range.getEnd());
+
+ return StringRef(
+ B,
+ E - B + Lexer::MeasureTokenLength(Range.getEnd(), SourceMgr, LangOpts));
+ }
+
// Run lexer over SourceText and collect FilenameRange from
// the InclusionDirective callback.
- CharSourceRange InclusionDirectiveFilenameRange(const char* SourceText,
- const char* HeaderPath, bool SystemHeader) {
+ CharSourceRange InclusionDirectiveFilenameRange(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)));
@@ -198,8 +231,38 @@ protected:
return Callbacks;
}
- PragmaOpenCLExtensionCallbacks::CallbackParameters
- PragmaOpenCLExtensionCall(const char* SourceText) {
+ std::vector<CondDirectiveCallbacks::Result>
+ DirectiveExprRange(StringRef SourceText) {
+ TrivialModuleLoader ModLoader;
+ MemoryBufferCache PCMCache;
+ std::unique_ptr<llvm::MemoryBuffer> Buf =
+ llvm::MemoryBuffer::getMemBuffer(SourceText);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
+ HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+ Diags, LangOpts, Target.get());
+ Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+ SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ /*IILookup =*/nullptr,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
+ auto *Callbacks = new CondDirectiveCallbacks;
+ PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
+
+ // Lex source text.
+ PP.EnterMainSourceFile();
+
+ while (true) {
+ Token Tok;
+ PP.Lex(Tok);
+ if (Tok.is(tok::eof))
+ break;
+ }
+
+ return Callbacks->Results;
+ }
+
+ PragmaOpenCLExtensionCallbacks::CallbackParameters
+ PragmaOpenCLExtensionCall(const char *SourceText) {
LangOptions OpenCLLangOpts;
OpenCLLangOpts.OpenCL = 1;
@@ -221,9 +284,8 @@ protected:
// parser actually sets correct pragma handlers for preprocessor
// according to LangOptions, so we init Parser to register opencl
// pragma handlers
- ASTContext Context(OpenCLLangOpts, SourceMgr,
- PP.getIdentifierTable(), PP.getSelectorTable(),
- PP.getBuiltinInfo());
+ ASTContext Context(OpenCLLangOpts, SourceMgr, PP.getIdentifierTable(),
+ PP.getSelectorTable(), PP.getBuiltinInfo());
Context.InitBuiltinTypes(*Target);
ASTConsumer Consumer;
@@ -245,7 +307,7 @@ protected:
Callbacks->Name,
Callbacks->State
};
- return RetVal;
+ return RetVal;
}
};
@@ -368,4 +430,17 @@ TEST_F(PPCallbacksTest, OpenCLExtensionPragmaDisabled) {
ASSERT_EQ(ExpectedState, Parameters.State);
}
-} // anonoymous namespace
+TEST_F(PPCallbacksTest, DirectiveExprRanges) {
+ const auto &Results8 =
+ DirectiveExprRange("#define FLOOFY 0\n#if __FILE__ > FLOOFY\n#endif\n");
+ EXPECT_EQ(Results8.size(), 1U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results8[0].ConditionRange, false)),
+ " __FILE__ > FLOOFY\n#");
+ EXPECT_EQ(
+ Lexer::getSourceText(CharSourceRange(Results8[0].ConditionRange, false),
+ SourceMgr, LangOpts),
+ " __FILE__ > FLOOFY\n");
+}
+
+} // namespace