diff options
author | Justin Bogner <mail@justinbogner.com> | 2014-05-20 21:43:27 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2014-05-20 21:43:27 +0000 |
commit | 99b5a85324c758f15a72fdf084240f3c2af8ce35 (patch) | |
tree | 9b59cdee6b4f29aa96613de81b9ef74ae98d0b1c /tools | |
parent | addbfc942181c163fe2fb2e436dcbcf0594ded1d (diff) | |
download | clang-99b5a85324c758f15a72fdf084240f3c2af8ce35.tar.gz clang-99b5a85324c758f15a72fdf084240f3c2af8ce35.tar.bz2 clang-99b5a85324c758f15a72fdf084240f3c2af8ce35.tar.xz |
VirtualFileSystem: Add YAMLVFSWriter to generate VFS mapping files
This moves the logic to write a JSON VFS mapping from the C api into
VirtualFileSystem, so that we can use it internally.
No functional change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209241 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libclang/BuildSystem.cpp | 150 |
1 files changed, 9 insertions, 141 deletions
diff --git a/tools/libclang/BuildSystem.cpp b/tools/libclang/BuildSystem.cpp index e5caa5447b..e9423c3286 100644 --- a/tools/libclang/BuildSystem.cpp +++ b/tools/libclang/BuildSystem.cpp @@ -13,13 +13,12 @@ #include "clang-c/BuildSystem.h" #include "CXString.h" -#include "llvm/ADT/ArrayRef.h" +#include "clang/Basic/VirtualFileSystem.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Optional.h" +#include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Path.h" #include "llvm/Support/TimeValue.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/YAMLParser.h" using namespace clang; using namespace llvm::sys; @@ -28,13 +27,11 @@ unsigned long long clang_getBuildSessionTimestamp(void) { return llvm::sys::TimeValue::now().toEpochTime(); } -struct CXVirtualFileOverlayImpl { - std::vector<std::pair<std::string, std::string> > Mappings; - Optional<bool> IsCaseSensitive; -}; +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::vfs::YAMLVFSWriter, + CXVirtualFileOverlay) CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) { - return new CXVirtualFileOverlayImpl(); + return wrap(new clang::vfs::YAMLVFSWriter()); } enum CXErrorCode @@ -56,7 +53,7 @@ clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO, return CXError_InvalidArguments; } - VFO->Mappings.push_back(std::make_pair(virtualPath, realPath)); + unwrap(VFO)->addFileMapping(virtualPath, realPath); return CXError_Success; } @@ -65,124 +62,10 @@ clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO, int caseSensitive) { if (!VFO) return CXError_InvalidArguments; - - VFO->IsCaseSensitive = caseSensitive; + unwrap(VFO)->setCaseSensitivity(caseSensitive); return CXError_Success; } -namespace { -struct EntryTy { - std::string VPath; - std::string RPath; - - friend bool operator < (const EntryTy &LHS, const EntryTy &RHS) { - return LHS.VPath < RHS.VPath; - } -}; - -class JSONVFSPrinter { - llvm::raw_ostream &OS; - CXVirtualFileOverlay VFO; - -public: - JSONVFSPrinter(llvm::raw_ostream &OS, CXVirtualFileOverlay VFO) - : OS(OS), VFO(VFO) {} - - /// Entries must be sorted. - void print(ArrayRef<EntryTy> Entries) { - OS << "{\n" - " 'version': 0,\n"; - if (VFO->IsCaseSensitive.hasValue()) { - OS << " 'case-sensitive': '"; - if (VFO->IsCaseSensitive.getValue()) - OS << "true"; - else - OS << "false"; - OS << "',\n"; - } - OS << " 'roots': [\n"; - printDirNodes(Entries, "", 4); - OS << " ]\n" - "}\n"; - } - -private: - ArrayRef<EntryTy> printDirNodes(ArrayRef<EntryTy> Entries, - StringRef ParentPath, - unsigned Indent) { - while (!Entries.empty()) { - const EntryTy &Entry = Entries.front(); - OS.indent(Indent) << "{\n"; - Indent += 2; - OS.indent(Indent) << "'type': 'directory',\n"; - StringRef DirName = containedPart(ParentPath, - path::parent_path(Entry.VPath)); - OS.indent(Indent) - << "'name': \"" << llvm::yaml::escape(DirName) << "\",\n"; - OS.indent(Indent) << "'contents': [\n"; - Entries = printContents(Entries, Indent + 2); - OS.indent(Indent) << "]\n"; - Indent -= 2; - OS.indent(Indent) << '}'; - if (Entries.empty()) { - OS << '\n'; - break; - } - StringRef NextVPath = Entries.front().VPath; - if (!containedIn(ParentPath, NextVPath)) { - OS << '\n'; - break; - } - OS << ",\n"; - } - return Entries; - } - - ArrayRef<EntryTy> printContents(ArrayRef<EntryTy> Entries, - unsigned Indent) { - while (!Entries.empty()) { - const EntryTy &Entry = Entries.front(); - Entries = Entries.slice(1); - StringRef ParentPath = path::parent_path(Entry.VPath); - StringRef VName = path::filename(Entry.VPath); - OS.indent(Indent) << "{\n"; - Indent += 2; - OS.indent(Indent) << "'type': 'file',\n"; - OS.indent(Indent) << "'name': \"" << llvm::yaml::escape(VName) << "\",\n"; - OS.indent(Indent) << "'external-contents': \"" - << llvm::yaml::escape(Entry.RPath) << "\"\n"; - Indent -= 2; - OS.indent(Indent) << '}'; - if (Entries.empty()) { - OS << '\n'; - break; - } - StringRef NextVPath = Entries.front().VPath; - if (!containedIn(ParentPath, NextVPath)) { - OS << '\n'; - break; - } - OS << ",\n"; - if (path::parent_path(NextVPath) != ParentPath) { - Entries = printDirNodes(Entries, ParentPath, Indent); - } - } - return Entries; - } - - bool containedIn(StringRef Parent, StringRef Path) { - return Path.startswith(Parent); - } - - StringRef containedPart(StringRef Parent, StringRef Path) { - assert(containedIn(Parent, Path)); - if (Parent.empty()) - return Path; - return Path.slice(Parent.size()+1, StringRef::npos); - } -}; -} - enum CXErrorCode clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, char **out_buffer_ptr, @@ -190,24 +73,9 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, if (!VFO || !out_buffer_ptr || !out_buffer_size) return CXError_InvalidArguments; - llvm::SmallVector<EntryTy, 16> Entries; - for (unsigned i = 0, e = VFO->Mappings.size(); i != e; ++i) { - EntryTy Entry; - Entry.VPath = VFO->Mappings[i].first; - Entry.RPath = VFO->Mappings[i].second; - Entries.push_back(Entry); - } - - // FIXME: We should add options to determine if the paths are case sensitive - // or not. The following assumes that if paths are case-insensitive the caller - // did not mix cases in the virtual paths it provided. - - std::sort(Entries.begin(), Entries.end()); - llvm::SmallString<256> Buf; llvm::raw_svector_ostream OS(Buf); - JSONVFSPrinter Printer(OS, VFO); - Printer.print(Entries); + unwrap(VFO)->write(OS); StringRef Data = OS.str(); *out_buffer_ptr = (char*)malloc(Data.size()); @@ -217,7 +85,7 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, } void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) { - delete VFO; + delete unwrap(VFO); } |