vladimir.plyashkun created this revision. vladimir.plyashkun added reviewers: alexfh, benlangmuir. vladimir.plyashkun added a project: clang-tools-extra. Herald added a subscriber: cfe-commits.
These changes introduce support for -vfsoverlay option in Clang-Tidy The main reason for it: In IDE integration we have two different pieces of source: editor and physical file. File is placed in some project directory (let's call it "A") We want to run clang-tidy exactly in this project directory "A", in order to get all .clang-tidy files in parent directories along with correct resolution for all relative include paths. But in IDE, saving mechanism perfoms periodically. So, to perform analysis of actual text on the fly, we need to save document on every modification (which is inefficient) or generate file in the temporary directory with actual text (it also leads to skipping .clang-tidy files and complicates include search paths resolution) -vfsoverlay approach allows us to analyze source file in the project directory "A" but with actual data placed in another directory. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D41535 Files: clang-tidy/ClangTidy.cpp clang-tidy/ClangTidyOptions.cpp clang-tidy/ClangTidyOptions.h clang-tidy/tool/ClangTidyMain.cpp
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<std::string> 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<ClangTidyOptions> ParsedConfig = @@ -331,7 +340,16 @@ } static int clangTidyMain(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory, + llvm::SpecificBumpPtrAllocator<char> ArgAllocator; + SmallVector<const char *, 256> 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(); 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<ArgList> ExtraArgsBefore; + + llvm::Optional<std::string> 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/ClangTidy.cpp =================================================================== --- clang-tidy/ClangTidy.cpp +++ clang-tidy/ClangTidy.cpp @@ -87,17 +87,41 @@ ClangTidyContext &Context; }; +void pushVfsOverlayFromFile(StringRef OverlayFile, + vfs::OverlayFileSystem &OverlayFS) { + if (OverlayFile.empty()) + return; + + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = + OverlayFS.getBufferForFile(OverlayFile); + if (!Buffer) { + return; + } + + IntrusiveRefCntPtr<vfs::FileSystem> 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<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts, DiagPrinter), SourceMgr(Diags, Files), Context(Context), ApplyFixes(ApplyFixes), 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<vfs::OverlayFileSystem> OverlayFS; FileManager Files; LangOptions LangOpts; // FIXME: use langopts from each original file IntrusiveRefCntPtr<DiagnosticOptions> 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) {}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits