1cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis//===- unittests/Lex/PPCallbacksTest.cpp - PPCallbacks tests ------===// 2cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// 3cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// The LLVM Compiler Infrastructure 4cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// 5cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 6cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// License. See LICENSE.TXT for details. 7cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// 8cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis//===--------------------------------------------------------------===// 9cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 101050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Lex/Preprocessor.h" 11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/ASTConsumer.h" 12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/ASTContext.h" 13cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/Basic/DiagnosticOptions.h" 15cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Basic/FileManager.h" 16cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Basic/LangOptions.h" 17cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Basic/SourceManager.h" 18cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 19cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Basic/TargetOptions.h" 20cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 21cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Lex/HeaderSearchOptions.h" 22cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Lex/ModuleLoader.h" 23cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "clang/Lex/PreprocessorOptions.h" 24a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen#include "clang/Parse/Parser.h" 25a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen#include "clang/Sema/Sema.h" 26cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "llvm/ADT/SmallString.h" 278229d22e6449851b89361bf2f41804557328be63Rafael Espindola#include "llvm/Support/Path.h" 28cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis#include "gtest/gtest.h" 29cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 30cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidisusing namespace clang; 31cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 32cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidisnamespace { 33cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 34cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// Stub out module loading. 35cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidisclass VoidModuleLoader : public ModuleLoader { 366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleLoadResult loadModule(SourceLocation ImportLoc, 376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleIdPath Path, 386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module::NameVisibilityKind Visibility, 396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool IsInclusionDirective) override { 407dff05bf3019995798def5d1066e4282b8578df6Douglas Gregor return ModuleLoadResult(); 41cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis } 421a4191d0697098c424646654784399b839f87bc4NAKAMURA Takumi 436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void makeModuleVisible(Module *Mod, 446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module::NameVisibilityKind Visibility, 45b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar SourceLocation ImportLoc) override { } 466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override 48c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines { return nullptr; } 496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override 5087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar { return 0; } 51cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis}; 52cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 53cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// Stub to collect data from InclusionDirective callbacks. 54cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidisclass InclusionDirectiveCallbacks : public PPCallbacks { 55cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidispublic: 5658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 5758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar StringRef FileName, bool IsAngled, 5858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar CharSourceRange FilenameRange, const FileEntry *File, 5958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar StringRef SearchPath, StringRef RelativePath, 6058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar const Module *Imported) override { 61cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->HashLoc = HashLoc; 62cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->IncludeTok = IncludeTok; 63cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->FileName = FileName.str(); 64cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->IsAngled = IsAngled; 65cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->FilenameRange = FilenameRange; 66cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->File = File; 67cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->SearchPath = SearchPath.str(); 68cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->RelativePath = RelativePath.str(); 69cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis this->Imported = Imported; 70cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis } 71cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 72cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis SourceLocation HashLoc; 73cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis Token IncludeTok; 74cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis SmallString<16> FileName; 75cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis bool IsAngled; 76cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange FilenameRange; 77cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const FileEntry* File; 78cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis SmallString<16> SearchPath; 79cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis SmallString<16> RelativePath; 80cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const Module* Imported; 81cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis}; 82cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 83a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen// Stub to collect data from PragmaOpenCLExtension callbacks. 84a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainenclass PragmaOpenCLExtensionCallbacks : public PPCallbacks { 85a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainenpublic: 86a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen typedef struct { 8774ecbd5babae58907e6338a5f79ec4eb4401c0dcAlexey Samsonov SmallString<16> Name; 88a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen unsigned State; 89a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen } CallbackParameters; 90a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 9187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar PragmaOpenCLExtensionCallbacks() : Name("Not called."), State(99) {} 92a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 9358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar void PragmaOpenCLExtension(clang::SourceLocation NameLoc, 9458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar const clang::IdentifierInfo *Name, 9558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar clang::SourceLocation StateLoc, 9658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar unsigned State) override { 97a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen this->NameLoc = NameLoc; 9874ecbd5babae58907e6338a5f79ec4eb4401c0dcAlexey Samsonov this->Name = Name->getName(); 99a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen this->StateLoc = StateLoc; 100a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen this->State = State; 10187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 102a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 103a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen SourceLocation NameLoc; 10474ecbd5babae58907e6338a5f79ec4eb4401c0dcAlexey Samsonov SmallString<16> Name; 105a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen SourceLocation StateLoc; 106a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen unsigned State; 107a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen}; 108a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 109cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis// PPCallbacks test fixture. 110cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidisclass PPCallbacksTest : public ::testing::Test { 111cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidisprotected: 112cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis PPCallbacksTest() 11387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : InMemoryFileSystem(new vfs::InMemoryFileSystem), 11487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar FileMgr(FileSystemOptions(), InMemoryFileSystem), 11587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DiagID(new DiagnosticIDs()), DiagOpts(new DiagnosticOptions()), 116c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()), 117c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) { 118cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis TargetOpts->Triple = "x86_64-apple-darwin11.1.0"; 119c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 120cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis } 121cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 12287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem; 123cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis FileManager FileMgr; 124cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis IntrusiveRefCntPtr<DiagnosticIDs> DiagID; 125cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; 126cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis DiagnosticsEngine Diags; 127cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis SourceManager SourceMgr; 128cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis LangOptions LangOpts; 129c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::shared_ptr<TargetOptions> TargetOpts; 130cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis IntrusiveRefCntPtr<TargetInfo> Target; 131cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 132cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // Register a header path as a known file and add its location 133cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // to search path. 134cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis void AddFakeHeader(HeaderSearch& HeaderInfo, const char* HeaderPath, 135cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis bool IsSystemHeader) { 136cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // Tell FileMgr about header. 13787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar InMemoryFileSystem->addFile(HeaderPath, 0, 13887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::MemoryBuffer::getMemBuffer("\n")); 139cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 140cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // Add header's parent path to search path. 141176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StringRef SearchPath = llvm::sys::path::parent_path(HeaderPath); 142cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const DirectoryEntry *DE = FileMgr.getDirectory(SearchPath); 1431ea6bc0fd9c1ff9fa03e8a829a79c4167445d503Daniel Dunbar DirectoryLookup DL(DE, SrcMgr::C_User, false); 144cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis HeaderInfo.AddSearchPath(DL, IsSystemHeader); 145cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis } 146cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 147cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // Get the raw source string of the range. 148cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis StringRef GetSourceString(CharSourceRange Range) { 149cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* B = SourceMgr.getCharacterData(Range.getBegin()); 150cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* E = SourceMgr.getCharacterData(Range.getEnd()); 151cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 152cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis return StringRef(B, E - B); 153cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis } 154cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 155cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // Run lexer over SourceText and collect FilenameRange from 156cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // the InclusionDirective callback. 157cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange InclusionDirectiveFilenameRange(const char* SourceText, 158cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* HeaderPath, bool SystemHeader) { 159176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::unique_ptr<llvm::MemoryBuffer> Buf = 160176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::MemoryBuffer::getMemBuffer(SourceText); 161176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); 162cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 163cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis VoidModuleLoader ModLoader; 164cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 165cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts = new HeaderSearchOptions(); 166ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts, 167c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Target.get()); 168cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader); 169cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 170cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis IntrusiveRefCntPtr<PreprocessorOptions> PPOpts = new PreprocessorOptions(); 1716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader, 172c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /*IILookup =*/nullptr, 1736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*OwnsHeaderSearch =*/false); 1746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PP.Initialize(*Target); 175cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks; 176176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks)); 177cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 178cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // Lex source text. 179cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis PP.EnterMainSourceFile(); 180cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 181cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis while (true) { 182cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis Token Tok; 183cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis PP.Lex(Tok); 184cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis if (Tok.is(tok::eof)) 185cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis break; 186cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis } 187cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 188cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis // Callbacks have been executed at this point -- return filename range. 189cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis return Callbacks->FilenameRange; 190cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis } 191a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 192a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCallbacks::CallbackParameters 193a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCall(const char* SourceText) { 194a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen LangOptions OpenCLLangOpts; 195a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen OpenCLLangOpts.OpenCL = 1; 196a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 197176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::unique_ptr<llvm::MemoryBuffer> SourceBuf = 198176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::MemoryBuffer::getMemBuffer(SourceText, "test.cl"); 199176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf))); 200a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 201a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen VoidModuleLoader ModLoader; 202ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, 203c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OpenCLLangOpts, Target.get()); 204a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 2056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, SourceMgr, 206c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines HeaderInfo, ModLoader, /*IILookup =*/nullptr, 2076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*OwnsHeaderSearch =*/false); 2086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PP.Initialize(*Target); 209a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 210a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen // parser actually sets correct pragma handlers for preprocessor 211a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen // according to LangOptions, so we init Parser to register opencl 212a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen // pragma handlers 2136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ASTContext Context(OpenCLLangOpts, SourceMgr, 214a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PP.getIdentifierTable(), PP.getSelectorTable(), 2156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PP.getBuiltinInfo()); 2166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Context.InitBuiltinTypes(*Target); 2176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 218a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen ASTConsumer Consumer; 219a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen Sema S(PP, Context, Consumer); 220a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen Parser P(PP, S, false); 221a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCallbacks* Callbacks = new PragmaOpenCLExtensionCallbacks; 222176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks)); 223a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 224a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen // Lex source text. 225a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PP.EnterMainSourceFile(); 226a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen while (true) { 227a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen Token Tok; 228a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PP.Lex(Tok); 229a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen if (Tok.is(tok::eof)) 230a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen break; 231a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen } 232a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 233a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCallbacks::CallbackParameters RetVal = { 23474ecbd5babae58907e6338a5f79ec4eb4401c0dcAlexey Samsonov Callbacks->Name, 235a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen Callbacks->State 236a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen }; 237a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen return RetVal; 238a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen } 239cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis}; 240cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 241cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, QuotedFilename) { 242cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 243cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#include \"quoted.h\"\n"; 244cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 245cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 246cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/quoted.h", false); 247cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 248cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis ASSERT_EQ("\"quoted.h\"", GetSourceString(Range)); 249cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 250cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 251cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, AngledFilename) { 252cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 253cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#include <angled.h>\n"; 254cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 255cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 256cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/angled.h", true); 257cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 258cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis ASSERT_EQ("<angled.h>", GetSourceString(Range)); 259cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 260cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 261cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, QuotedInMacro) { 262cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 263cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#define MACRO_QUOTED \"quoted.h\"\n" 264cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#include MACRO_QUOTED\n"; 265cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 266cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 267cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/quoted.h", false); 268cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 269cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis ASSERT_EQ("\"quoted.h\"", GetSourceString(Range)); 270cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 271cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 272cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, AngledInMacro) { 273cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 274cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#define MACRO_ANGLED <angled.h>\n" 275cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#include MACRO_ANGLED\n"; 276cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 277cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 278cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/angled.h", true); 279cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 280cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis ASSERT_EQ("<angled.h>", GetSourceString(Range)); 281cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 282cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 283cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, StringizedMacroArgument) { 284cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 285cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#define MACRO_STRINGIZED(x) #x\n" 286cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#include MACRO_STRINGIZED(quoted.h)\n"; 287cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 288cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 289cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/quoted.h", false); 290cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 291cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis ASSERT_EQ("\"quoted.h\"", GetSourceString(Range)); 292cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 293cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 294cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, ConcatenatedMacroArgument) { 295cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 296cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#define MACRO_ANGLED <angled.h>\n" 297cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#define MACRO_CONCAT(x, y) x ## _ ## y\n" 298cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#include MACRO_CONCAT(MACRO, ANGLED)\n"; 299cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 300cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 301cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/angled.h", false); 302cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 303cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis ASSERT_EQ("<angled.h>", GetSourceString(Range)); 304cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 305cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 306cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, TrigraphFilename) { 307cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 3087164095ea1c804740e00d54d05a7e8d1f876c674Benjamin Kramer "#include \"tri\?\?-graph.h\"\n"; 309cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 310cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 311cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/tri~graph.h", false); 312cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 3137164095ea1c804740e00d54d05a7e8d1f876c674Benjamin Kramer ASSERT_EQ("\"tri\?\?-graph.h\"", GetSourceString(Range)); 314cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 315cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 316cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios KyrtzidisTEST_F(PPCallbacksTest, TrigraphInMacro) { 317cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis const char* Source = 3187164095ea1c804740e00d54d05a7e8d1f876c674Benjamin Kramer "#define MACRO_TRIGRAPH \"tri\?\?-graph.h\"\n" 319cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis "#include MACRO_TRIGRAPH\n"; 320cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 321cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis CharSourceRange Range = 322cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis InclusionDirectiveFilenameRange(Source, "/tri~graph.h", false); 323cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 3247164095ea1c804740e00d54d05a7e8d1f876c674Benjamin Kramer ASSERT_EQ("\"tri\?\?-graph.h\"", GetSourceString(Range)); 325cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} 326cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis 327a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka JaaskelainenTEST_F(PPCallbacksTest, OpenCLExtensionPragmaEnabled) { 328a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen const char* Source = 329a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"; 330a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 331a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCallbacks::CallbackParameters Parameters = 332a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCall(Source); 333a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 334a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen ASSERT_EQ("cl_khr_fp64", Parameters.Name); 335a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen unsigned ExpectedState = 1; 336a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen ASSERT_EQ(ExpectedState, Parameters.State); 337a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen} 338a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 339a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka JaaskelainenTEST_F(PPCallbacksTest, OpenCLExtensionPragmaDisabled) { 340a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen const char* Source = 341a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen "#pragma OPENCL EXTENSION cl_khr_fp16 : disable\n"; 342a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 343a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCallbacks::CallbackParameters Parameters = 344a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen PragmaOpenCLExtensionCall(Source); 345a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 346a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen ASSERT_EQ("cl_khr_fp16", Parameters.Name); 347a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen unsigned ExpectedState = 0; 348a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen ASSERT_EQ(ExpectedState, Parameters.State); 349a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen} 350a0950e83cae5df77c00d02d7f77a166979cd2b8bPekka Jaaskelainen 351cfa1caa92611184f59c2f3e606c53ddcc726449aArgyrios Kyrtzidis} // anonoymous namespace 352