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