xref: /minix3/external/bsd/llvm/dist/clang/unittests/Lex/PPCallbacksTest.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- unittests/Lex/PPCallbacksTest.cpp - PPCallbacks tests ------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===--------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
11*0a6a1f1dSLionel Sambuc #include "clang/AST/ASTConsumer.h"
12*0a6a1f1dSLionel Sambuc #include "clang/AST/ASTContext.h"
13f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
14*0a6a1f1dSLionel Sambuc #include "clang/Basic/DiagnosticOptions.h"
15f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
16f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.h"
17f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
18f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
19f4a2713aSLionel Sambuc #include "clang/Basic/TargetOptions.h"
20f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h"
21f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearchOptions.h"
22f4a2713aSLionel Sambuc #include "clang/Lex/ModuleLoader.h"
23f4a2713aSLionel Sambuc #include "clang/Lex/PreprocessorOptions.h"
24f4a2713aSLionel Sambuc #include "clang/Parse/Parser.h"
25f4a2713aSLionel Sambuc #include "clang/Sema/Sema.h"
26f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
27f4a2713aSLionel Sambuc #include "llvm/Support/Path.h"
28f4a2713aSLionel Sambuc #include "gtest/gtest.h"
29f4a2713aSLionel Sambuc 
30f4a2713aSLionel Sambuc using namespace clang;
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc namespace {
33f4a2713aSLionel Sambuc 
34f4a2713aSLionel Sambuc // Stub out module loading.
35f4a2713aSLionel Sambuc class VoidModuleLoader : public ModuleLoader {
loadModule(SourceLocation ImportLoc,ModuleIdPath Path,Module::NameVisibilityKind Visibility,bool IsInclusionDirective)36*0a6a1f1dSLionel Sambuc   ModuleLoadResult loadModule(SourceLocation ImportLoc,
37f4a2713aSLionel Sambuc                               ModuleIdPath Path,
38f4a2713aSLionel Sambuc                               Module::NameVisibilityKind Visibility,
39*0a6a1f1dSLionel Sambuc                               bool IsInclusionDirective) override {
40f4a2713aSLionel Sambuc     return ModuleLoadResult();
41f4a2713aSLionel Sambuc   }
42f4a2713aSLionel Sambuc 
makeModuleVisible(Module * Mod,Module::NameVisibilityKind Visibility,SourceLocation ImportLoc,bool Complain)43*0a6a1f1dSLionel Sambuc   void makeModuleVisible(Module *Mod,
44f4a2713aSLionel Sambuc                          Module::NameVisibilityKind Visibility,
45f4a2713aSLionel Sambuc                          SourceLocation ImportLoc,
46*0a6a1f1dSLionel Sambuc                          bool Complain) override { }
47*0a6a1f1dSLionel Sambuc 
loadGlobalModuleIndex(SourceLocation TriggerLoc)48*0a6a1f1dSLionel Sambuc   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
49*0a6a1f1dSLionel Sambuc     { return nullptr; }
lookupMissingImports(StringRef Name,SourceLocation TriggerLoc)50*0a6a1f1dSLionel Sambuc   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
51*0a6a1f1dSLionel Sambuc     { return 0; };
52f4a2713aSLionel Sambuc };
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc // Stub to collect data from InclusionDirective callbacks.
55f4a2713aSLionel Sambuc class InclusionDirectiveCallbacks : public PPCallbacks {
56f4a2713aSLionel Sambuc public:
InclusionDirective(SourceLocation HashLoc,const Token & IncludeTok,StringRef FileName,bool IsAngled,CharSourceRange FilenameRange,const FileEntry * File,StringRef SearchPath,StringRef RelativePath,const Module * Imported)57f4a2713aSLionel Sambuc   void InclusionDirective(SourceLocation HashLoc,
58f4a2713aSLionel Sambuc     const Token &IncludeTok,
59f4a2713aSLionel Sambuc     StringRef FileName,
60f4a2713aSLionel Sambuc     bool IsAngled,
61f4a2713aSLionel Sambuc     CharSourceRange FilenameRange,
62f4a2713aSLionel Sambuc     const FileEntry *File,
63f4a2713aSLionel Sambuc     StringRef SearchPath,
64f4a2713aSLionel Sambuc     StringRef RelativePath,
65f4a2713aSLionel Sambuc     const Module *Imported) {
66f4a2713aSLionel Sambuc       this->HashLoc = HashLoc;
67f4a2713aSLionel Sambuc       this->IncludeTok = IncludeTok;
68f4a2713aSLionel Sambuc       this->FileName = FileName.str();
69f4a2713aSLionel Sambuc       this->IsAngled = IsAngled;
70f4a2713aSLionel Sambuc       this->FilenameRange = FilenameRange;
71f4a2713aSLionel Sambuc       this->File = File;
72f4a2713aSLionel Sambuc       this->SearchPath = SearchPath.str();
73f4a2713aSLionel Sambuc       this->RelativePath = RelativePath.str();
74f4a2713aSLionel Sambuc       this->Imported = Imported;
75f4a2713aSLionel Sambuc   }
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc   SourceLocation HashLoc;
78f4a2713aSLionel Sambuc   Token IncludeTok;
79f4a2713aSLionel Sambuc   SmallString<16> FileName;
80f4a2713aSLionel Sambuc   bool IsAngled;
81f4a2713aSLionel Sambuc   CharSourceRange FilenameRange;
82f4a2713aSLionel Sambuc   const FileEntry* File;
83f4a2713aSLionel Sambuc   SmallString<16> SearchPath;
84f4a2713aSLionel Sambuc   SmallString<16> RelativePath;
85f4a2713aSLionel Sambuc   const Module* Imported;
86f4a2713aSLionel Sambuc };
87f4a2713aSLionel Sambuc 
88f4a2713aSLionel Sambuc // Stub to collect data from PragmaOpenCLExtension callbacks.
89f4a2713aSLionel Sambuc class PragmaOpenCLExtensionCallbacks : public PPCallbacks {
90f4a2713aSLionel Sambuc public:
91f4a2713aSLionel Sambuc   typedef struct {
92f4a2713aSLionel Sambuc     SmallString<16> Name;
93f4a2713aSLionel Sambuc     unsigned State;
94f4a2713aSLionel Sambuc   } CallbackParameters;
95f4a2713aSLionel Sambuc 
PragmaOpenCLExtensionCallbacks()96f4a2713aSLionel Sambuc   PragmaOpenCLExtensionCallbacks() : Name("Not called."), State(99) {};
97f4a2713aSLionel Sambuc 
PragmaOpenCLExtension(clang::SourceLocation NameLoc,const clang::IdentifierInfo * Name,clang::SourceLocation StateLoc,unsigned State)98f4a2713aSLionel Sambuc   void PragmaOpenCLExtension(
99f4a2713aSLionel Sambuc     clang::SourceLocation NameLoc, const clang::IdentifierInfo *Name,
100f4a2713aSLionel Sambuc     clang::SourceLocation StateLoc, unsigned State) {
101f4a2713aSLionel Sambuc       this->NameLoc = NameLoc;
102f4a2713aSLionel Sambuc       this->Name = Name->getName();
103f4a2713aSLionel Sambuc       this->StateLoc = StateLoc;
104f4a2713aSLionel Sambuc       this->State = State;
105f4a2713aSLionel Sambuc   };
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc   SourceLocation NameLoc;
108f4a2713aSLionel Sambuc   SmallString<16> Name;
109f4a2713aSLionel Sambuc   SourceLocation StateLoc;
110f4a2713aSLionel Sambuc   unsigned State;
111f4a2713aSLionel Sambuc };
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc // PPCallbacks test fixture.
114f4a2713aSLionel Sambuc class PPCallbacksTest : public ::testing::Test {
115f4a2713aSLionel Sambuc protected:
PPCallbacksTest()116f4a2713aSLionel Sambuc   PPCallbacksTest()
117*0a6a1f1dSLionel Sambuc       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
118f4a2713aSLionel Sambuc         DiagOpts(new DiagnosticOptions()),
119*0a6a1f1dSLionel Sambuc         Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
120*0a6a1f1dSLionel Sambuc         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
121f4a2713aSLionel Sambuc     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
122*0a6a1f1dSLionel Sambuc     Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
123f4a2713aSLionel Sambuc   }
124f4a2713aSLionel Sambuc 
125f4a2713aSLionel Sambuc   FileSystemOptions FileMgrOpts;
126f4a2713aSLionel Sambuc   FileManager FileMgr;
127f4a2713aSLionel Sambuc   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
128f4a2713aSLionel Sambuc   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
129f4a2713aSLionel Sambuc   DiagnosticsEngine Diags;
130f4a2713aSLionel Sambuc   SourceManager SourceMgr;
131f4a2713aSLionel Sambuc   LangOptions LangOpts;
132*0a6a1f1dSLionel Sambuc   std::shared_ptr<TargetOptions> TargetOpts;
133f4a2713aSLionel Sambuc   IntrusiveRefCntPtr<TargetInfo> Target;
134f4a2713aSLionel Sambuc 
135f4a2713aSLionel Sambuc   // Register a header path as a known file and add its location
136f4a2713aSLionel Sambuc   // to search path.
AddFakeHeader(HeaderSearch & HeaderInfo,const char * HeaderPath,bool IsSystemHeader)137f4a2713aSLionel Sambuc   void AddFakeHeader(HeaderSearch& HeaderInfo, const char* HeaderPath,
138f4a2713aSLionel Sambuc     bool IsSystemHeader) {
139f4a2713aSLionel Sambuc       // Tell FileMgr about header.
140f4a2713aSLionel Sambuc       FileMgr.getVirtualFile(HeaderPath, 0, 0);
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc       // Add header's parent path to search path.
143*0a6a1f1dSLionel Sambuc       StringRef SearchPath = llvm::sys::path::parent_path(HeaderPath);
144f4a2713aSLionel Sambuc       const DirectoryEntry *DE = FileMgr.getDirectory(SearchPath);
145f4a2713aSLionel Sambuc       DirectoryLookup DL(DE, SrcMgr::C_User, false);
146f4a2713aSLionel Sambuc       HeaderInfo.AddSearchPath(DL, IsSystemHeader);
147f4a2713aSLionel Sambuc   }
148f4a2713aSLionel Sambuc 
149f4a2713aSLionel Sambuc   // Get the raw source string of the range.
GetSourceString(CharSourceRange Range)150f4a2713aSLionel Sambuc   StringRef GetSourceString(CharSourceRange Range) {
151f4a2713aSLionel Sambuc     const char* B = SourceMgr.getCharacterData(Range.getBegin());
152f4a2713aSLionel Sambuc     const char* E = SourceMgr.getCharacterData(Range.getEnd());
153f4a2713aSLionel Sambuc 
154f4a2713aSLionel Sambuc     return StringRef(B, E - B);
155f4a2713aSLionel Sambuc   }
156f4a2713aSLionel Sambuc 
157f4a2713aSLionel Sambuc   // Run lexer over SourceText and collect FilenameRange from
158f4a2713aSLionel Sambuc   // the InclusionDirective callback.
InclusionDirectiveFilenameRange(const char * SourceText,const char * HeaderPath,bool SystemHeader)159f4a2713aSLionel Sambuc   CharSourceRange InclusionDirectiveFilenameRange(const char* SourceText,
160f4a2713aSLionel Sambuc       const char* HeaderPath, bool SystemHeader) {
161*0a6a1f1dSLionel Sambuc     std::unique_ptr<llvm::MemoryBuffer> Buf =
162*0a6a1f1dSLionel Sambuc         llvm::MemoryBuffer::getMemBuffer(SourceText);
163*0a6a1f1dSLionel Sambuc     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
164f4a2713aSLionel Sambuc 
165f4a2713aSLionel Sambuc     VoidModuleLoader ModLoader;
166f4a2713aSLionel Sambuc 
167f4a2713aSLionel Sambuc     IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts = new HeaderSearchOptions();
168f4a2713aSLionel Sambuc     HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts,
169*0a6a1f1dSLionel Sambuc                             Target.get());
170f4a2713aSLionel Sambuc     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
171f4a2713aSLionel Sambuc 
172f4a2713aSLionel Sambuc     IntrusiveRefCntPtr<PreprocessorOptions> PPOpts = new PreprocessorOptions();
173*0a6a1f1dSLionel Sambuc     Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader,
174*0a6a1f1dSLionel Sambuc                     /*IILookup =*/nullptr,
175*0a6a1f1dSLionel Sambuc                     /*OwnsHeaderSearch =*/false);
176*0a6a1f1dSLionel Sambuc     PP.Initialize(*Target);
177f4a2713aSLionel Sambuc     InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks;
178*0a6a1f1dSLionel Sambuc     PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
179f4a2713aSLionel Sambuc 
180f4a2713aSLionel Sambuc     // Lex source text.
181f4a2713aSLionel Sambuc     PP.EnterMainSourceFile();
182f4a2713aSLionel Sambuc 
183f4a2713aSLionel Sambuc     while (true) {
184f4a2713aSLionel Sambuc       Token Tok;
185f4a2713aSLionel Sambuc       PP.Lex(Tok);
186f4a2713aSLionel Sambuc       if (Tok.is(tok::eof))
187f4a2713aSLionel Sambuc         break;
188f4a2713aSLionel Sambuc     }
189f4a2713aSLionel Sambuc 
190f4a2713aSLionel Sambuc     // Callbacks have been executed at this point -- return filename range.
191f4a2713aSLionel Sambuc     return Callbacks->FilenameRange;
192f4a2713aSLionel Sambuc   }
193f4a2713aSLionel Sambuc 
194f4a2713aSLionel Sambuc   PragmaOpenCLExtensionCallbacks::CallbackParameters
PragmaOpenCLExtensionCall(const char * SourceText)195f4a2713aSLionel Sambuc   PragmaOpenCLExtensionCall(const char* SourceText) {
196f4a2713aSLionel Sambuc     LangOptions OpenCLLangOpts;
197f4a2713aSLionel Sambuc     OpenCLLangOpts.OpenCL = 1;
198f4a2713aSLionel Sambuc 
199*0a6a1f1dSLionel Sambuc     std::unique_ptr<llvm::MemoryBuffer> SourceBuf =
200*0a6a1f1dSLionel Sambuc         llvm::MemoryBuffer::getMemBuffer(SourceText, "test.cl");
201*0a6a1f1dSLionel Sambuc     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
202f4a2713aSLionel Sambuc 
203f4a2713aSLionel Sambuc     VoidModuleLoader ModLoader;
204f4a2713aSLionel Sambuc     HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags,
205*0a6a1f1dSLionel Sambuc                             OpenCLLangOpts, Target.get());
206f4a2713aSLionel Sambuc 
207*0a6a1f1dSLionel Sambuc     Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, SourceMgr,
208*0a6a1f1dSLionel Sambuc                     HeaderInfo, ModLoader, /*IILookup =*/nullptr,
209*0a6a1f1dSLionel Sambuc                     /*OwnsHeaderSearch =*/false);
210*0a6a1f1dSLionel Sambuc     PP.Initialize(*Target);
211f4a2713aSLionel Sambuc 
212f4a2713aSLionel Sambuc     // parser actually sets correct pragma handlers for preprocessor
213f4a2713aSLionel Sambuc     // according to LangOptions, so we init Parser to register opencl
214f4a2713aSLionel Sambuc     // pragma handlers
215*0a6a1f1dSLionel Sambuc     ASTContext Context(OpenCLLangOpts, SourceMgr,
216f4a2713aSLionel Sambuc                        PP.getIdentifierTable(), PP.getSelectorTable(),
217*0a6a1f1dSLionel Sambuc                        PP.getBuiltinInfo());
218*0a6a1f1dSLionel Sambuc     Context.InitBuiltinTypes(*Target);
219*0a6a1f1dSLionel Sambuc 
220f4a2713aSLionel Sambuc     ASTConsumer Consumer;
221f4a2713aSLionel Sambuc     Sema S(PP, Context, Consumer);
222f4a2713aSLionel Sambuc     Parser P(PP, S, false);
223f4a2713aSLionel Sambuc     PragmaOpenCLExtensionCallbacks* Callbacks = new PragmaOpenCLExtensionCallbacks;
224*0a6a1f1dSLionel Sambuc     PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
225f4a2713aSLionel Sambuc 
226f4a2713aSLionel Sambuc     // Lex source text.
227f4a2713aSLionel Sambuc     PP.EnterMainSourceFile();
228f4a2713aSLionel Sambuc     while (true) {
229f4a2713aSLionel Sambuc       Token Tok;
230f4a2713aSLionel Sambuc       PP.Lex(Tok);
231f4a2713aSLionel Sambuc       if (Tok.is(tok::eof))
232f4a2713aSLionel Sambuc         break;
233f4a2713aSLionel Sambuc     }
234f4a2713aSLionel Sambuc 
235f4a2713aSLionel Sambuc     PragmaOpenCLExtensionCallbacks::CallbackParameters RetVal = {
236f4a2713aSLionel Sambuc       Callbacks->Name,
237f4a2713aSLionel Sambuc       Callbacks->State
238f4a2713aSLionel Sambuc     };
239f4a2713aSLionel Sambuc     return RetVal;
240f4a2713aSLionel Sambuc   }
241f4a2713aSLionel Sambuc };
242f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,QuotedFilename)243f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, QuotedFilename) {
244f4a2713aSLionel Sambuc   const char* Source =
245f4a2713aSLionel Sambuc     "#include \"quoted.h\"\n";
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc   CharSourceRange Range =
248f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/quoted.h", false);
249f4a2713aSLionel Sambuc 
250f4a2713aSLionel Sambuc   ASSERT_EQ("\"quoted.h\"", GetSourceString(Range));
251f4a2713aSLionel Sambuc }
252f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,AngledFilename)253f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, AngledFilename) {
254f4a2713aSLionel Sambuc   const char* Source =
255f4a2713aSLionel Sambuc     "#include <angled.h>\n";
256f4a2713aSLionel Sambuc 
257f4a2713aSLionel Sambuc   CharSourceRange Range =
258f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/angled.h", true);
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc   ASSERT_EQ("<angled.h>", GetSourceString(Range));
261f4a2713aSLionel Sambuc }
262f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,QuotedInMacro)263f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, QuotedInMacro) {
264f4a2713aSLionel Sambuc   const char* Source =
265f4a2713aSLionel Sambuc     "#define MACRO_QUOTED \"quoted.h\"\n"
266f4a2713aSLionel Sambuc     "#include MACRO_QUOTED\n";
267f4a2713aSLionel Sambuc 
268f4a2713aSLionel Sambuc   CharSourceRange Range =
269f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/quoted.h", false);
270f4a2713aSLionel Sambuc 
271f4a2713aSLionel Sambuc   ASSERT_EQ("\"quoted.h\"", GetSourceString(Range));
272f4a2713aSLionel Sambuc }
273f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,AngledInMacro)274f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, AngledInMacro) {
275f4a2713aSLionel Sambuc   const char* Source =
276f4a2713aSLionel Sambuc     "#define MACRO_ANGLED <angled.h>\n"
277f4a2713aSLionel Sambuc     "#include MACRO_ANGLED\n";
278f4a2713aSLionel Sambuc 
279f4a2713aSLionel Sambuc   CharSourceRange Range =
280f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/angled.h", true);
281f4a2713aSLionel Sambuc 
282f4a2713aSLionel Sambuc   ASSERT_EQ("<angled.h>", GetSourceString(Range));
283f4a2713aSLionel Sambuc }
284f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,StringizedMacroArgument)285f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, StringizedMacroArgument) {
286f4a2713aSLionel Sambuc   const char* Source =
287f4a2713aSLionel Sambuc     "#define MACRO_STRINGIZED(x) #x\n"
288f4a2713aSLionel Sambuc     "#include MACRO_STRINGIZED(quoted.h)\n";
289f4a2713aSLionel Sambuc 
290f4a2713aSLionel Sambuc   CharSourceRange Range =
291f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/quoted.h", false);
292f4a2713aSLionel Sambuc 
293f4a2713aSLionel Sambuc   ASSERT_EQ("\"quoted.h\"", GetSourceString(Range));
294f4a2713aSLionel Sambuc }
295f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,ConcatenatedMacroArgument)296f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, ConcatenatedMacroArgument) {
297f4a2713aSLionel Sambuc   const char* Source =
298f4a2713aSLionel Sambuc     "#define MACRO_ANGLED <angled.h>\n"
299f4a2713aSLionel Sambuc     "#define MACRO_CONCAT(x, y) x ## _ ## y\n"
300f4a2713aSLionel Sambuc     "#include MACRO_CONCAT(MACRO, ANGLED)\n";
301f4a2713aSLionel Sambuc 
302f4a2713aSLionel Sambuc   CharSourceRange Range =
303f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/angled.h", false);
304f4a2713aSLionel Sambuc 
305f4a2713aSLionel Sambuc   ASSERT_EQ("<angled.h>", GetSourceString(Range));
306f4a2713aSLionel Sambuc }
307f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,TrigraphFilename)308f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, TrigraphFilename) {
309f4a2713aSLionel Sambuc   const char* Source =
310f4a2713aSLionel Sambuc     "#include \"tri\?\?-graph.h\"\n";
311f4a2713aSLionel Sambuc 
312f4a2713aSLionel Sambuc   CharSourceRange Range =
313f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/tri~graph.h", false);
314f4a2713aSLionel Sambuc 
315f4a2713aSLionel Sambuc   ASSERT_EQ("\"tri\?\?-graph.h\"", GetSourceString(Range));
316f4a2713aSLionel Sambuc }
317f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,TrigraphInMacro)318f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, TrigraphInMacro) {
319f4a2713aSLionel Sambuc   const char* Source =
320f4a2713aSLionel Sambuc     "#define MACRO_TRIGRAPH \"tri\?\?-graph.h\"\n"
321f4a2713aSLionel Sambuc     "#include MACRO_TRIGRAPH\n";
322f4a2713aSLionel Sambuc 
323f4a2713aSLionel Sambuc   CharSourceRange Range =
324f4a2713aSLionel Sambuc     InclusionDirectiveFilenameRange(Source, "/tri~graph.h", false);
325f4a2713aSLionel Sambuc 
326f4a2713aSLionel Sambuc   ASSERT_EQ("\"tri\?\?-graph.h\"", GetSourceString(Range));
327f4a2713aSLionel Sambuc }
328f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,OpenCLExtensionPragmaEnabled)329f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, OpenCLExtensionPragmaEnabled) {
330f4a2713aSLionel Sambuc   const char* Source =
331f4a2713aSLionel Sambuc     "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
332f4a2713aSLionel Sambuc 
333f4a2713aSLionel Sambuc   PragmaOpenCLExtensionCallbacks::CallbackParameters Parameters =
334f4a2713aSLionel Sambuc     PragmaOpenCLExtensionCall(Source);
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc   ASSERT_EQ("cl_khr_fp64", Parameters.Name);
337f4a2713aSLionel Sambuc   unsigned ExpectedState = 1;
338f4a2713aSLionel Sambuc   ASSERT_EQ(ExpectedState, Parameters.State);
339f4a2713aSLionel Sambuc }
340f4a2713aSLionel Sambuc 
TEST_F(PPCallbacksTest,OpenCLExtensionPragmaDisabled)341f4a2713aSLionel Sambuc TEST_F(PPCallbacksTest, OpenCLExtensionPragmaDisabled) {
342f4a2713aSLionel Sambuc   const char* Source =
343f4a2713aSLionel Sambuc     "#pragma OPENCL EXTENSION cl_khr_fp16 : disable\n";
344f4a2713aSLionel Sambuc 
345f4a2713aSLionel Sambuc   PragmaOpenCLExtensionCallbacks::CallbackParameters Parameters =
346f4a2713aSLionel Sambuc     PragmaOpenCLExtensionCall(Source);
347f4a2713aSLionel Sambuc 
348f4a2713aSLionel Sambuc   ASSERT_EQ("cl_khr_fp16", Parameters.Name);
349f4a2713aSLionel Sambuc   unsigned ExpectedState = 0;
350f4a2713aSLionel Sambuc   ASSERT_EQ(ExpectedState, Parameters.State);
351f4a2713aSLionel Sambuc }
352f4a2713aSLionel Sambuc 
353f4a2713aSLionel Sambuc } // anonoymous namespace
354