xref: /llvm-project/clang-tools-extra/unittests/include/common/VirtualFileHelper.h (revision b1aea98cfa357e23f4bb52232da5f41781f23bff)
1 //===--- VirtualFileHelper.h ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// This file defines an utility class for tests that needs a source
10 /// manager for a virtual file with customizable content.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H
15 #define CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H
16 
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/DiagnosticOptions.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/SourceManager.h"
21 #include "clang/Frontend/TextDiagnosticPrinter.h"
22 
23 namespace clang {
24 
25 /// Class that provides easy access to a SourceManager and that allows to
26 /// map virtual files conveniently.
27 class VirtualFileHelper {
28   struct VirtualFile {
29     std::string FileName;
30     std::string Code;
31   };
32 
33 public:
34   VirtualFileHelper()
35       : DiagOpts(new DiagnosticOptions()),
36         Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
37                     &*DiagOpts),
38         DiagnosticPrinter(llvm::outs(), &*DiagOpts),
39         Files((FileSystemOptions())) {}
40 
41   /// Create a virtual file \p FileName, with content \p Code.
42   void mapFile(llvm::StringRef FileName, llvm::StringRef Code) {
43     VirtualFile VF = { FileName, Code };
44     VirtualFiles.push_back(VF);
45   }
46 
47   /// Create a new \c SourceManager with the virtual files and contents
48   /// mapped to it.
49   SourceManager &getNewSourceManager() {
50     Sources.reset(new SourceManager(Diagnostics, Files));
51     mapVirtualFiles(*Sources);
52     return *Sources;
53   }
54 
55   /// Map the virtual file contents in the given \c SourceManager.
56   void mapVirtualFiles(SourceManager &SM) const {
57     for (llvm::SmallVectorImpl<VirtualFile>::const_iterator
58              I = VirtualFiles.begin(),
59              E = VirtualFiles.end();
60          I != E; ++I) {
61       std::unique_ptr<llvm::MemoryBuffer> Buf =
62           llvm::MemoryBuffer::getMemBuffer(I->Code);
63       FileEntryRef Entry = SM.getFileManager().getVirtualFileRef(
64           I->FileName, Buf->getBufferSize(), /*ModificationTime=*/0);
65       SM.overrideFileContents(Entry, std::move(Buf));
66     }
67   }
68 
69 private:
70   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
71   DiagnosticsEngine Diagnostics;
72   TextDiagnosticPrinter DiagnosticPrinter;
73   FileManager Files;
74   // most tests don't need more than one file
75   llvm::SmallVector<VirtualFile, 1> VirtualFiles;
76   std::unique_ptr<SourceManager> Sources;
77 };
78 
79 } // end namespace clang
80 
81 #endif // CLANG_MODERNIZE_VIRTUAL_FILE_HELPER_H
82