1abc3d04eSRaphael Isemann //===- unittests/Frontend/CompilerInstanceTest.cpp - CI tests -------------===//
2abc3d04eSRaphael Isemann //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6abc3d04eSRaphael Isemann //
7abc3d04eSRaphael Isemann //===----------------------------------------------------------------------===//
8abc3d04eSRaphael Isemann 
9abc3d04eSRaphael Isemann #include "clang/Frontend/CompilerInstance.h"
10abc3d04eSRaphael Isemann #include "clang/Frontend/CompilerInvocation.h"
11abc3d04eSRaphael Isemann #include "llvm/Support/FileSystem.h"
12abc3d04eSRaphael Isemann #include "llvm/Support/Format.h"
13abc3d04eSRaphael Isemann #include "llvm/Support/ToolOutputFile.h"
14abc3d04eSRaphael Isemann #include "gtest/gtest.h"
15abc3d04eSRaphael Isemann 
16abc3d04eSRaphael Isemann using namespace llvm;
17abc3d04eSRaphael Isemann using namespace clang;
18abc3d04eSRaphael Isemann 
19abc3d04eSRaphael Isemann namespace {
20abc3d04eSRaphael Isemann 
21abc3d04eSRaphael Isemann TEST(CompilerInstance, DefaultVFSOverlayFromInvocation) {
22abc3d04eSRaphael Isemann   // Create a temporary VFS overlay yaml file.
23abc3d04eSRaphael Isemann   int FD;
24abc3d04eSRaphael Isemann   SmallString<256> FileName;
25abc3d04eSRaphael Isemann   ASSERT_FALSE(sys::fs::createTemporaryFile("vfs", "yaml", FD, FileName));
262590edf6SReid Kleckner   ToolOutputFile File(FileName, FD);
27abc3d04eSRaphael Isemann 
28abc3d04eSRaphael Isemann   SmallString<256> CurrentPath;
29abc3d04eSRaphael Isemann   sys::fs::current_path(CurrentPath);
30abc3d04eSRaphael Isemann   sys::fs::make_absolute(CurrentPath, FileName);
31abc3d04eSRaphael Isemann 
32abc3d04eSRaphael Isemann   // Mount the VFS file itself on the path 'virtual.file'. Makes this test
33abc3d04eSRaphael Isemann   // a bit shorter than creating a new dummy file just for this purpose.
34abc3d04eSRaphael Isemann   const std::string CurrentPathStr = CurrentPath.str();
35abc3d04eSRaphael Isemann   const std::string FileNameStr = FileName.str();
36abc3d04eSRaphael Isemann   const char *VFSYaml = "{ 'version': 0, 'roots': [\n"
37abc3d04eSRaphael Isemann                         "  { 'name': '%s',\n"
38abc3d04eSRaphael Isemann                         "    'type': 'directory',\n"
39abc3d04eSRaphael Isemann                         "    'contents': [\n"
40abc3d04eSRaphael Isemann                         "      { 'name': 'vfs-virtual.file', 'type': 'file',\n"
41abc3d04eSRaphael Isemann                         "        'external-contents': '%s'\n"
42abc3d04eSRaphael Isemann                         "      }\n"
43abc3d04eSRaphael Isemann                         "    ]\n"
44abc3d04eSRaphael Isemann                         "  }\n"
45abc3d04eSRaphael Isemann                         "]}\n";
46abc3d04eSRaphael Isemann   File.os() << format(VFSYaml, CurrentPathStr.c_str(), FileName.c_str());
47abc3d04eSRaphael Isemann   File.os().flush();
48abc3d04eSRaphael Isemann 
49abc3d04eSRaphael Isemann   // Create a CompilerInvocation that uses this overlay file.
50abc3d04eSRaphael Isemann   const std::string VFSArg = "-ivfsoverlay" + FileNameStr;
51abc3d04eSRaphael Isemann   const char *Args[] = {"clang", VFSArg.c_str(), "-xc++", "-"};
52abc3d04eSRaphael Isemann 
53abc3d04eSRaphael Isemann   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
54abc3d04eSRaphael Isemann       CompilerInstance::createDiagnostics(new DiagnosticOptions());
55abc3d04eSRaphael Isemann 
56abc3d04eSRaphael Isemann   std::shared_ptr<CompilerInvocation> CInvok =
57abc3d04eSRaphael Isemann       createInvocationFromCommandLine(Args, Diags);
58abc3d04eSRaphael Isemann 
59abc3d04eSRaphael Isemann   if (!CInvok)
60abc3d04eSRaphael Isemann     FAIL() << "could not create compiler invocation";
61abc3d04eSRaphael Isemann   // Create a minimal CompilerInstance which should use the VFS we specified
62abc3d04eSRaphael Isemann   // in the CompilerInvocation (as we don't explicitly set our own).
63abc3d04eSRaphael Isemann   CompilerInstance Instance;
64abc3d04eSRaphael Isemann   Instance.setDiagnostics(Diags.get());
65abc3d04eSRaphael Isemann   Instance.setInvocation(CInvok);
66abc3d04eSRaphael Isemann   Instance.createFileManager();
67abc3d04eSRaphael Isemann 
68abc3d04eSRaphael Isemann   // Check if the virtual file exists which means that our VFS is used by the
69abc3d04eSRaphael Isemann   // CompilerInstance.
70abc3d04eSRaphael Isemann   ASSERT_TRUE(Instance.getFileManager().getFile("vfs-virtual.file"));
71abc3d04eSRaphael Isemann }
72abc3d04eSRaphael Isemann 
73abc3d04eSRaphael Isemann } // anonymous namespace
74