Index: clang-tidy/ClangTidy.cpp =================================================================== --- clang-tidy/ClangTidy.cpp +++ clang-tidy/ClangTidy.cpp @@ -87,10 +87,30 @@ ClangTidyContext &Context; }; +void pushVfsOverlayFromFile(StringRef OverlayFile, + vfs::OverlayFileSystem &OverlayFS) { + if (OverlayFile.empty()) + return; + + llvm::ErrorOr> Buffer = + OverlayFS.getBufferForFile(OverlayFile); + if (!Buffer) { + return; + } + + IntrusiveRefCntPtr FS = vfs::getVFSFromYAML( + std::move(Buffer.get()), /*DiagHandler*/ nullptr, OverlayFile); + if (!FS.get()) { + return; + } + OverlayFS.pushOverlay(FS); +} + class ErrorReporter { public: ErrorReporter(ClangTidyContext &Context, bool ApplyFixes) - : Files(FileSystemOptions()), DiagOpts(new DiagnosticOptions()), + : OverlayFS(new vfs::OverlayFileSystem(vfs::getRealFileSystem())), + Files(FileSystemOptions(), OverlayFS), DiagOpts(new DiagnosticOptions()), DiagPrinter(new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts)), Diags(IntrusiveRefCntPtr(new DiagnosticIDs), &*DiagOpts, DiagPrinter), @@ -98,6 +118,10 @@ TotalFixes(0), AppliedFixes(0), WarningsAsErrors(0) { DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors(); DiagPrinter->BeginSourceFile(LangOpts); + + if (Context.getOptions().VfsOverlay) { + pushVfsOverlayFromFile(*Context.getOptions().VfsOverlay, *OverlayFS); + } } SourceManager &getSourceManager() { return SourceMgr; } @@ -249,6 +273,7 @@ << Message.Message; } + IntrusiveRefCntPtr OverlayFS; FileManager Files; LangOptions LangOpts; // FIXME: use langopts from each original file IntrusiveRefCntPtr DiagOpts; @@ -520,6 +545,10 @@ Tool.setDiagnosticConsumer(&DiagConsumer); + if (Context.getOptions().VfsOverlay) { + pushVfsOverlayFromFile(*Context.getOptions().VfsOverlay, Tool.getOverlayFileSystem()); + } + class ActionFactory : public FrontendActionFactory { public: ActionFactory(ClangTidyContext &Context) : ConsumerFactory(Context) {} Index: clang-tidy/ClangTidyOptions.h =================================================================== --- clang-tidy/ClangTidyOptions.h +++ clang-tidy/ClangTidyOptions.h @@ -108,6 +108,8 @@ /// \brief Add extra compilation arguments to the start of the list. llvm::Optional ExtraArgsBefore; + + llvm::Optional VfsOverlay; }; /// \brief Abstract interface for retrieving various ClangTidy options. Index: clang-tidy/ClangTidyOptions.cpp =================================================================== --- clang-tidy/ClangTidyOptions.cpp +++ clang-tidy/ClangTidyOptions.cpp @@ -92,6 +92,7 @@ IO.mapOptional("CheckOptions", NOpts->Options); IO.mapOptional("ExtraArgs", Options.ExtraArgs); IO.mapOptional("ExtraArgsBefore", Options.ExtraArgsBefore); + IO.mapOptional("VfsOverlay", Options.VfsOverlay); } }; @@ -152,6 +153,7 @@ overrideValue(Result.User, Other.User); mergeVectors(Result.ExtraArgs, Other.ExtraArgs); mergeVectors(Result.ExtraArgsBefore, Other.ExtraArgsBefore); + overrideValue(Result.VfsOverlay, Other.VfsOverlay); for (const auto &KeyValue : Other.CheckOptions) Result.CheckOptions[KeyValue.first] = KeyValue.second; Index: clang-tidy/tool/ClangTidyMain.cpp =================================================================== --- clang-tidy/tool/ClangTidyMain.cpp +++ clang-tidy/tool/ClangTidyMain.cpp @@ -209,6 +209,12 @@ cl::init(false), cl::cat(ClangTidyCategory)); +static cl::opt VfsOverlay("vfsoverlay", cl::desc(R"( +Overlay the virtual filesystem described by file over the real file system. +)"), + cl::value_desc("filename"), + cl::cat(ClangTidyCategory)); + namespace clang { namespace tidy { @@ -295,6 +301,7 @@ DefaultOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors; DefaultOptions.FormatStyle = FormatStyle; DefaultOptions.User = llvm::sys::Process::GetEnv("USER"); + DefaultOptions.VfsOverlay = VfsOverlay; // USERNAME is used on Windows. if (!DefaultOptions.User) DefaultOptions.User = llvm::sys::Process::GetEnv("USERNAME"); @@ -312,6 +319,8 @@ OverrideOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors; if (FormatStyle.getNumOccurrences() > 0) OverrideOptions.FormatStyle = FormatStyle; + if (VfsOverlay.getNumOccurrences() > 0) + OverrideOptions.VfsOverlay = VfsOverlay; if (!Config.empty()) { if (llvm::ErrorOr ParsedConfig = @@ -331,7 +340,16 @@ } static int clangTidyMain(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory, + llvm::SpecificBumpPtrAllocator ArgAllocator; + SmallVector Argv; + std::error_code EC = llvm::sys::Process::GetArgumentVector( + Argv, llvm::makeArrayRef(argv, argc), ArgAllocator); + if (EC) { + llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n'; + return 1; + } + + CommonOptionsParser OptionsParser(argc, &Argv[0], ClangTidyCategory, cl::ZeroOrMore); auto OwningOptionsProvider = createOptionsProvider();