Skip to content

Commit 9deba01

Browse files
authored
[support] Use VFS in SourceMgr for loading includes (#162903)
Most `SourceMgr` clients don't make use of include files, but those that do might want to specify the file system to use. This patch enables that by making it possible to pass a `vfs::FileSystem` instance into `SourceMgr`.
1 parent 097f1e7 commit 9deba01

File tree

17 files changed

+93
-12
lines changed

17 files changed

+93
-12
lines changed

clang/tools/driver/cc1as_main.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,8 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) {
417417
}
418418

419419
static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
420-
DiagnosticsEngine &Diags) {
420+
DiagnosticsEngine &Diags,
421+
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
421422
// Get the target specific parser.
422423
std::string Error;
423424
const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
@@ -440,6 +441,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
440441
// Record the location of the include directories so that the lexer can find
441442
// it later.
442443
SrcMgr.setIncludeDirs(Opts.IncludePaths);
444+
SrcMgr.setVirtualFileSystem(VFS);
443445

444446
std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
445447
assert(MRI && "Unable to create target register info!");
@@ -632,8 +634,9 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
632634
}
633635

634636
static bool ExecuteAssembler(AssemblerInvocation &Opts,
635-
DiagnosticsEngine &Diags) {
636-
bool Failed = ExecuteAssemblerImpl(Opts, Diags);
637+
DiagnosticsEngine &Diags,
638+
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
639+
bool Failed = ExecuteAssemblerImpl(Opts, Diags, VFS);
637640

638641
// Delete output file if there were errors.
639642
if (Failed) {
@@ -714,7 +717,7 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
714717
}
715718

716719
// Execute the invocation, unless there were parsing errors.
717-
bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags);
720+
bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags, VFS);
718721

719722
// If any timers were active but haven't been destroyed yet, print their
720723
// results now.

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define LLVM_CODEGEN_ASMPRINTER_H
1717

1818
#include "llvm/ADT/DenseMap.h"
19+
#include "llvm/ADT/IntrusiveRefCntPtr.h"
1920
#include "llvm/ADT/MapVector.h"
2021
#include "llvm/ADT/SmallSet.h"
2122
#include "llvm/ADT/SmallVector.h"
@@ -87,6 +88,10 @@ namespace remarks {
8788
class RemarkStreamer;
8889
}
8990

91+
namespace vfs {
92+
class FileSystem;
93+
}
94+
9095
/// This class is intended to be used as a driving class for all asm writers.
9196
class LLVM_ABI AsmPrinter : public MachineFunctionPass {
9297
public:
@@ -105,6 +110,9 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
105110
/// generating (such as the current section etc).
106111
std::unique_ptr<MCStreamer> OutStreamer;
107112

113+
/// The VFS to resolve asm include directives.
114+
IntrusiveRefCntPtr<vfs::FileSystem> VFS;
115+
108116
/// The current machine function.
109117
MachineFunction *MF = nullptr;
110118

llvm/include/llvm/Support/SourceMgr.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef LLVM_SUPPORT_SOURCEMGR_H
1616
#define LLVM_SUPPORT_SOURCEMGR_H
1717

18+
#include "llvm/ADT/IntrusiveRefCntPtr.h"
1819
#include "llvm/ADT/SmallVector.h"
1920
#include "llvm/Support/Compiler.h"
2021
#include "llvm/Support/MemoryBuffer.h"
@@ -23,6 +24,10 @@
2324

2425
namespace llvm {
2526

27+
namespace vfs {
28+
class FileSystem;
29+
} // end namespace vfs
30+
2631
class raw_ostream;
2732
class SMDiagnostic;
2833
class SMFixIt;
@@ -91,15 +96,25 @@ class SourceMgr {
9196
DiagHandlerTy DiagHandler = nullptr;
9297
void *DiagContext = nullptr;
9398

99+
// Optional file system for finding include files.
100+
IntrusiveRefCntPtr<vfs::FileSystem> FS;
101+
94102
bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
95103

96104
public:
97-
SourceMgr() = default;
105+
/// Create new source manager without support for include files.
106+
SourceMgr();
107+
/// Create new source manager with the capability of finding include files
108+
/// via the provided file system.
109+
explicit SourceMgr(IntrusiveRefCntPtr<vfs::FileSystem> FS);
98110
SourceMgr(const SourceMgr &) = delete;
99111
SourceMgr &operator=(const SourceMgr &) = delete;
100-
SourceMgr(SourceMgr &&) = default;
101-
SourceMgr &operator=(SourceMgr &&) = default;
102-
~SourceMgr() = default;
112+
SourceMgr(SourceMgr &&);
113+
SourceMgr &operator=(SourceMgr &&);
114+
~SourceMgr();
115+
116+
IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const;
117+
void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS);
103118

104119
/// Return the include directories of this source manager.
105120
ArrayRef<std::string> getIncludeDirs() const { return IncludeDirectories; }

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
#include "llvm/Support/MathExtras.h"
120120
#include "llvm/Support/Path.h"
121121
#include "llvm/Support/VCSRevision.h"
122+
#include "llvm/Support/VirtualFileSystem.h"
122123
#include "llvm/Support/raw_ostream.h"
123124
#include "llvm/Target/TargetLoweringObjectFile.h"
124125
#include "llvm/Target/TargetMachine.h"
@@ -476,6 +477,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
476477
}
477478

478479
bool AsmPrinter::doInitialization(Module &M) {
480+
VFS = vfs::getRealFileSystem();
479481
auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
480482
MMI = MMIWP ? &MMIWP->getMMI() : nullptr;
481483
HasSplitStack = false;

llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/Support/ErrorHandling.h"
3737
#include "llvm/Support/MemoryBuffer.h"
3838
#include "llvm/Support/SourceMgr.h"
39+
#include "llvm/Support/VirtualFileSystem.h"
3940
#include "llvm/Support/raw_ostream.h"
4041
#include "llvm/Target/TargetMachine.h"
4142
using namespace llvm;
@@ -98,6 +99,7 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
9899
unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode);
99100
SourceMgr &SrcMgr = *MMI->getContext().getInlineSourceManager();
100101
SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
102+
SrcMgr.setVirtualFileSystem(VFS);
101103

102104
std::unique_ptr<MCAsmParser> Parser(
103105
createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));

llvm/lib/Support/SourceMgr.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/Support/MemoryBuffer.h"
2525
#include "llvm/Support/Path.h"
2626
#include "llvm/Support/SMLoc.h"
27+
#include "llvm/Support/VirtualFileSystem.h"
2728
#include "llvm/Support/WithColor.h"
2829
#include "llvm/Support/raw_ostream.h"
2930
#include <algorithm>
@@ -38,6 +39,22 @@ using namespace llvm;
3839

3940
static const size_t TabStop = 8;
4041

42+
// Out of line to avoid needing definition of vfs::FileSystem in header.
43+
SourceMgr::SourceMgr() = default;
44+
SourceMgr::SourceMgr(IntrusiveRefCntPtr<vfs::FileSystem> FS)
45+
: FS(std::move(FS)) {}
46+
SourceMgr::SourceMgr(SourceMgr &&) = default;
47+
SourceMgr &SourceMgr::operator=(SourceMgr &&) = default;
48+
SourceMgr::~SourceMgr() = default;
49+
50+
IntrusiveRefCntPtr<vfs::FileSystem> SourceMgr::getVirtualFileSystem() const {
51+
return FS;
52+
}
53+
54+
void SourceMgr::setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) {
55+
this->FS = std::move(FS);
56+
}
57+
4158
unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
4259
SMLoc IncludeLoc,
4360
std::string &IncludedFile) {
@@ -52,16 +69,19 @@ unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
5269
ErrorOr<std::unique_ptr<MemoryBuffer>>
5370
SourceMgr::OpenIncludeFile(const std::string &Filename,
5471
std::string &IncludedFile) {
72+
if (!FS)
73+
reportFatalInternalError("Opening include file from SourceMgr without VFS");
74+
5575
ErrorOr<std::unique_ptr<MemoryBuffer>> NewBufOrErr =
56-
MemoryBuffer::getFile(Filename);
76+
FS->getBufferForFile(Filename);
5777

5878
SmallString<64> Buffer(Filename);
5979
// If the file didn't exist directly, see if it's in an include path.
6080
for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
6181
++i) {
6282
Buffer = IncludeDirectories[i];
6383
sys::path::append(Buffer, Filename);
64-
NewBufOrErr = MemoryBuffer::getFile(Buffer);
84+
NewBufOrErr = FS->getBufferForFile(Buffer);
6585
}
6686

6787
if (NewBufOrErr)

llvm/lib/TableGen/Main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/Support/SMLoc.h"
2727
#include "llvm/Support/SourceMgr.h"
2828
#include "llvm/Support/ToolOutputFile.h"
29+
#include "llvm/Support/VirtualFileSystem.h"
2930
#include "llvm/Support/raw_ostream.h"
3031
#include "llvm/TableGen/Error.h"
3132
#include "llvm/TableGen/Record.h"
@@ -128,6 +129,7 @@ int llvm::TableGenMain(const char *argv0,
128129
// Record the location of the include directory so that the lexer can find
129130
// it later.
130131
SrcMgr.setIncludeDirs(IncludeDirs);
132+
SrcMgr.setVirtualFileSystem(vfs::getRealFileSystem());
131133

132134
TGParser Parser(SrcMgr, MacroNames, Records, NoWarnOnUnusedTemplateArgs);
133135

llvm/lib/TableGen/Parser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "llvm/TableGen/Parser.h"
1010
#include "TGParser.h"
1111
#include "llvm/Support/MemoryBuffer.h"
12+
#include "llvm/Support/VirtualFileSystem.h"
1213
#include "llvm/TableGen/Record.h"
1314

1415
using namespace llvm;
@@ -21,6 +22,7 @@ bool llvm::TableGenParseFile(SourceMgr &InputSrcMgr, RecordKeeper &Records) {
2122
SrcMgr = SourceMgr();
2223
SrcMgr.takeSourceBuffersFrom(InputSrcMgr);
2324
SrcMgr.setIncludeDirs(InputSrcMgr.getIncludeDirs());
25+
SrcMgr.setVirtualFileSystem(InputSrcMgr.getVirtualFileSystem());
2426
SrcMgr.setDiagHandler(InputSrcMgr.getDiagHandler(),
2527
InputSrcMgr.getDiagContext());
2628

llvm/tools/llvm-mc-assemble-fuzzer/llvm-mc-assemble-fuzzer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/Support/SourceMgr.h"
3232
#include "llvm/Support/TargetSelect.h"
3333
#include "llvm/Support/ToolOutputFile.h"
34+
#include "llvm/Support/VirtualFileSystem.h"
3435
#include "llvm/Support/raw_ostream.h"
3536
#include "llvm/TargetParser/Host.h"
3637
#include "llvm/TargetParser/SubtargetFeature.h"
@@ -142,6 +143,7 @@ int AssembleOneInput(const uint8_t *Data, size_t Size) {
142143

143144
static const std::vector<std::string> NoIncludeDirs;
144145
SrcMgr.setIncludeDirs(NoIncludeDirs);
146+
SrcMgr.setVirtualFileSystem(vfs::getRealFileSystem());
145147

146148
static std::string ArchName;
147149
std::string Error;

llvm/tools/llvm-mc/llvm-mc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "llvm/Support/TargetSelect.h"
4141
#include "llvm/Support/TimeProfiler.h"
4242
#include "llvm/Support/ToolOutputFile.h"
43+
#include "llvm/Support/VirtualFileSystem.h"
4344
#include "llvm/Support/WithColor.h"
4445
#include "llvm/TargetParser/Host.h"
4546
#include <memory>
@@ -439,6 +440,7 @@ int main(int argc, char **argv) {
439440
// Record the location of the include directories so that the lexer can find
440441
// it later.
441442
SrcMgr.setIncludeDirs(IncludeDirs);
443+
SrcMgr.setVirtualFileSystem(vfs::getRealFileSystem());
442444

443445
std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TheTriple));
444446
assert(MRI && "Unable to create target register info!");

0 commit comments

Comments
 (0)