Author: eugenezelenko Date: Wed Mar 28 15:09:09 2018 New Revision: 328735 URL: http://llvm.org/viewvc/llvm-project?rev=328735&view=rev Log: [Basic] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
Modified: cfe/trunk/include/clang/Basic/AddressSpaces.h cfe/trunk/include/clang/Basic/CommentOptions.h cfe/trunk/include/clang/Basic/FileSystemStatCache.h cfe/trunk/include/clang/Basic/Linkage.h cfe/trunk/include/clang/Basic/ObjCRuntime.h cfe/trunk/include/clang/Basic/Sanitizers.h cfe/trunk/include/clang/Basic/VirtualFileSystem.h cfe/trunk/lib/Basic/FileSystemStatCache.cpp cfe/trunk/lib/Basic/ObjCRuntime.cpp cfe/trunk/lib/Basic/Sanitizers.cpp cfe/trunk/lib/Basic/VirtualFileSystem.cpp Modified: cfe/trunk/include/clang/Basic/AddressSpaces.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AddressSpaces.h?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/AddressSpaces.h (original) +++ cfe/trunk/include/clang/Basic/AddressSpaces.h Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- AddressSpaces.h - Language-specific address spaces -----*- C++ -*-===// +//===- AddressSpaces.h - Language-specific address spaces -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,17 +6,17 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Provides definitions for the various language-specific address /// spaces. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H #define LLVM_CLANG_BASIC_ADDRESSSPACES_H -#include <assert.h> +#include <cassert> namespace clang { @@ -51,7 +51,7 @@ enum class LangAS : unsigned { /// The type of a lookup table which maps from language-specific address spaces /// to target-specific ones. -typedef unsigned LangASMap[(unsigned)LangAS::FirstTargetAddressSpace]; +using LangASMap = unsigned[(unsigned)LangAS::FirstTargetAddressSpace]; /// \return whether \p AS is a target-specific address space rather than a /// clang AST address space @@ -71,4 +71,4 @@ inline LangAS getLangASFromTargetAS(unsi } // namespace clang -#endif +#endif // LLVM_CLANG_BASIC_ADDRESSSPACES_H Modified: cfe/trunk/include/clang/Basic/CommentOptions.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/CommentOptions.h?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/CommentOptions.h (original) +++ cfe/trunk/include/clang/Basic/CommentOptions.h Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- CommentOptions.h - Options for parsing comments -----*- C++ -*-===// +//===- CommentOptions.h - Options for parsing comments ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,10 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the clang::CommentOptions interface. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_COMMENTOPTIONS_H @@ -22,18 +22,18 @@ namespace clang { /// \brief Options for controlling comment parsing. struct CommentOptions { - typedef std::vector<std::string> BlockCommandNamesTy; + using BlockCommandNamesTy = std::vector<std::string>; /// \brief Command names to treat as block commands in comments. /// Should not include the leading backslash. BlockCommandNamesTy BlockCommandNames; /// \brief Treat ordinary comments as documentation comments. - bool ParseAllComments; + bool ParseAllComments = false; - CommentOptions() : ParseAllComments(false) { } + CommentOptions() = default; }; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_BASIC_COMMENTOPTIONS_H Modified: cfe/trunk/include/clang/Basic/FileSystemStatCache.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileSystemStatCache.h?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/FileSystemStatCache.h (original) +++ cfe/trunk/include/clang/Basic/FileSystemStatCache.h Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- FileSystemStatCache.h - Caching for 'stat' calls -------*- C++ -*-===// +//===- FileSystemStatCache.h - Caching for 'stat' calls ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,10 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the FileSystemStatCache interface. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H @@ -17,29 +17,38 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/FileSystem.h" +#include <cstdint> +#include <ctime> #include <memory> +#include <string> +#include <utility> namespace clang { namespace vfs { + class File; class FileSystem; -} + +} // namespace vfs // FIXME: should probably replace this with vfs::Status struct FileData { std::string Name; - uint64_t Size; - time_t ModTime; + uint64_t Size = 0; + time_t ModTime = 0; llvm::sys::fs::UniqueID UniqueID; - bool IsDirectory; - bool IsNamedPipe; - bool InPCH; - bool IsVFSMapped; // FIXME: remove this when files support multiple names - FileData() - : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false), - InPCH(false), IsVFSMapped(false) {} + bool IsDirectory = false; + bool IsNamedPipe = false; + bool InPCH = false; + + // FIXME: remove this when files support multiple names + bool IsVFSMapped = false; + + FileData() = default; }; /// \brief Abstract interface for introducing a FileManager cache for 'stat' @@ -47,15 +56,19 @@ struct FileData { /// improve performance. class FileSystemStatCache { virtual void anchor(); + protected: std::unique_ptr<FileSystemStatCache> NextStatCache; public: - virtual ~FileSystemStatCache() {} + virtual ~FileSystemStatCache() = default; enum LookupResult { - CacheExists, ///< We know the file exists and its cached stat data. - CacheMissing ///< We know that the file doesn't exist. + /// We know the file exists and its cached stat data. + CacheExists, + + /// We know that the file doesn't exist. + CacheMissing }; /// \brief Get the 'stat' information for the specified path, using the cache @@ -115,8 +128,8 @@ public: /// \brief The set of stat() calls that have been seen. llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls; - typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator - iterator; + using iterator = + llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator; iterator begin() const { return StatCalls.begin(); } iterator end() const { return StatCalls.end(); } @@ -126,6 +139,6 @@ public: vfs::FileSystem &FS) override; }; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H Modified: cfe/trunk/include/clang/Basic/Linkage.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Linkage.h?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Linkage.h (original) +++ cfe/trunk/include/clang/Basic/Linkage.h Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- Linkage.h - Linkage enumeration and utilities ----------*- C++ -*-===// +//===- Linkage.h - Linkage enumeration and utilities ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,16 +6,15 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the Linkage enumeration and various utility functions. -/// +// //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_BASIC_LINKAGE_H #define LLVM_CLANG_BASIC_LINKAGE_H -#include <assert.h> -#include <stdint.h> #include <utility> namespace clang { @@ -125,6 +124,6 @@ inline Linkage minLinkage(Linkage L1, Li return L1 < L2 ? L1 : L2; } -} // end namespace clang +} // namespace clang #endif // LLVM_CLANG_BASIC_LINKAGE_H Modified: cfe/trunk/include/clang/Basic/ObjCRuntime.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/ObjCRuntime.h?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/ObjCRuntime.h (original) +++ cfe/trunk/include/clang/Basic/ObjCRuntime.h Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- ObjCRuntime.h - Objective-C Runtime Configuration ------*- C++ -*-===// +//===- ObjCRuntime.h - Objective-C Runtime Configuration --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,18 +6,21 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines types useful for describing an Objective-C runtime. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_OBJCRUNTIME_H #define LLVM_CLANG_BASIC_OBJCRUNTIME_H +#include "clang/Basic/LLVM.h" #include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/ErrorHandling.h" +#include <string> namespace clang { @@ -57,15 +60,14 @@ public: }; private: - Kind TheKind; + Kind TheKind = MacOSX; VersionTuple Version; public: /// A bogus initialization of the runtime. - ObjCRuntime() : TheKind(MacOSX) {} - + ObjCRuntime() = default; ObjCRuntime(Kind kind, const VersionTuple &version) - : TheKind(kind), Version(version) {} + : TheKind(kind), Version(version) {} void set(Kind kind, VersionTuple version) { TheKind = kind; @@ -182,9 +184,8 @@ public: return true; case GNUstep: return getVersion() >= VersionTuple(1, 7); - default: - return false; + return false; } } @@ -320,7 +321,6 @@ public: return getVersion() >= VersionTuple(2); case GNUstep: return false; - default: return false; } @@ -360,6 +360,6 @@ public: raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value); -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_BASIC_OBJCRUNTIME_H Modified: cfe/trunk/include/clang/Basic/Sanitizers.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Sanitizers.h?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Sanitizers.h (original) +++ cfe/trunk/include/clang/Basic/Sanitizers.h Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- Sanitizers.h - C Language Family Language Options ------*- C++ -*-===// +//===- Sanitizers.h - C Language Family Language Options --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,10 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the clang::SanitizerKind enum. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_SANITIZERS_H @@ -18,10 +18,12 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/MathExtras.h" +#include <cassert> +#include <cstdint> namespace clang { -typedef uint64_t SanitizerMask; +using SanitizerMask = uint64_t; namespace SanitizerKind { @@ -43,7 +45,7 @@ enum SanitizerOrdinal : uint64_t { const SanitizerMask ID##Group = 1ULL << SO_##ID##Group; #include "clang/Basic/Sanitizers.def" -} +} // namespace SanitizerKind struct SanitizerSet { /// \brief Check if a certain (single) sanitizer is enabled. @@ -85,6 +87,6 @@ inline SanitizerMask getPPTransparentSan SanitizerKind::Nullability | SanitizerKind::Undefined; } -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_BASIC_SANITIZERS_H Modified: cfe/trunk/include/clang/Basic/VirtualFileSystem.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/VirtualFileSystem.h?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/VirtualFileSystem.h (original) +++ cfe/trunk/include/clang/Basic/VirtualFileSystem.h Wed Mar 28 15:09:09 2018 @@ -6,8 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// /// \file /// \brief Defines the virtual file system interface vfs::FileSystem. +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H @@ -15,6 +17,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -23,8 +26,6 @@ #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/SourceMgr.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> #include <cassert> #include <cstdint> #include <ctime> @@ -39,7 +40,7 @@ namespace llvm { class MemoryBuffer; -} // end namespace llvm +} // namespace llvm namespace clang { namespace vfs { @@ -52,14 +53,14 @@ class Status { uint32_t User; uint32_t Group; uint64_t Size; - llvm::sys::fs::file_type Type; + llvm::sys::fs::file_type Type = llvm::sys::fs::file_type::status_error; llvm::sys::fs::perms Perms; public: - bool IsVFSMapped; // FIXME: remove when files support multiple names + // FIXME: remove when files support multiple names + bool IsVFSMapped = false; -public: - Status() : Type(llvm::sys::fs::file_type::status_error) {} + Status() = default; Status(const llvm::sys::fs::file_status &Status); Status(StringRef Name, llvm::sys::fs::UniqueID UID, llvm::sys::TimePoint<> MTime, uint32_t User, uint32_t Group, @@ -139,7 +140,7 @@ struct DirIterImpl { Status CurrentEntry; }; -} // end namespace detail +} // namespace detail /// \brief An input iterator over the entries in a virtual path, similar to /// llvm::sys::fs::directory_iterator. @@ -184,8 +185,8 @@ class FileSystem; /// \brief An input iterator over the recursive contents of a virtual path, /// similar to llvm::sys::fs::recursive_directory_iterator. class recursive_directory_iterator { - typedef std::stack<directory_iterator, std::vector<directory_iterator>> - IterState; + using IterState = + std::stack<directory_iterator, std::vector<directory_iterator>>; FileSystem *FS; std::shared_ptr<IterState> State; // Input iterator semantics on copy. @@ -193,6 +194,7 @@ class recursive_directory_iterator { public: recursive_directory_iterator(FileSystem &FS, const Twine &Path, std::error_code &EC); + /// \brief Construct an 'end' iterator. recursive_directory_iterator() = default; @@ -211,7 +213,7 @@ public: /// \brief Gets the current level. Starting path is at level 0. int level() const { - assert(State->size() && "Cannot get level without any iteration state"); + assert(!State->empty() && "Cannot get level without any iteration state"); return State->size()-1; } }; @@ -223,6 +225,7 @@ public: /// \brief Get the status of the entry at \p Path, if one exists. virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0; + /// \brief Get a \p File object for the file at \p Path, if one exists. virtual llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) = 0; @@ -241,6 +244,7 @@ public: /// Set the working directory. This will affect all following operations on /// this file system and may propagate down for nested file systems. virtual std::error_code setCurrentWorkingDirectory(const Twine &Path) = 0; + /// Get the working directory of this file system. virtual llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const = 0; @@ -276,13 +280,15 @@ IntrusiveRefCntPtr<FileSystem> getRealFi /// that exists in more than one file system, the file in the top-most file /// system overrides the other(s). class OverlayFileSystem : public FileSystem { - typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList; + using FileSystemList = SmallVector<IntrusiveRefCntPtr<FileSystem>, 1>; + /// \brief The stack of file systems, implemented as a list in order of /// their addition. FileSystemList FSList; public: OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base); + /// \brief Pushes a file system on top of the stack. void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS); @@ -293,7 +299,7 @@ public: llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; - typedef FileSystemList::reverse_iterator iterator; + using iterator = FileSystemList::reverse_iterator; /// \brief Get an iterator pointing to the most recently added file system. iterator overlays_begin() { return FSList.rbegin(); } @@ -307,7 +313,7 @@ namespace detail { class InMemoryDirectory; -} // end namespace detail +} // namespace detail /// An in-memory file system. class InMemoryFileSystem : public FileSystem { @@ -330,6 +336,7 @@ public: Optional<uint32_t> User = None, Optional<uint32_t> Group = None, Optional<llvm::sys::fs::file_type> Type = None, Optional<llvm::sys::fs::perms> Perms = None); + /// Add a buffer to the VFS with a path. The VFS does not own the buffer. /// If present, User, Group, Type and Perms apply to the newly-created file /// or directory. @@ -344,6 +351,7 @@ public: Optional<llvm::sys::fs::perms> Perms = None); std::string toString() const; + /// Return true if this file system normalizes . and .. in paths. bool useNormalizedPaths() const { return UseNormalizedPaths; } @@ -351,9 +359,11 @@ public: llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; + llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { return WorkingDirectory; } + std::error_code setCurrentWorkingDirectory(const Twine &Path) override; }; @@ -419,7 +429,7 @@ public: void write(llvm::raw_ostream &OS); }; -} // end namespace vfs -} // end namespace clang +} // namespace vfs +} // namespace clang #endif // LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H Modified: cfe/trunk/lib/Basic/FileSystemStatCache.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileSystemStatCache.cpp?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/lib/Basic/FileSystemStatCache.cpp (original) +++ cfe/trunk/lib/Basic/FileSystemStatCache.cpp Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- FileSystemStatCache.cpp - Caching for 'stat' calls ---------------===// +//===- FileSystemStatCache.cpp - Caching for 'stat' calls -----------------===// // // The LLVM Compiler Infrastructure // @@ -13,11 +13,14 @@ #include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/VirtualFileSystem.h" +#include "llvm/Support/Chrono.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/Path.h" +#include <utility> using namespace clang; -void FileSystemStatCache::anchor() { } +void FileSystemStatCache::anchor() {} static void copyStatusToFileData(const vfs::Status &Status, FileData &Data) { Modified: cfe/trunk/lib/Basic/ObjCRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/ObjCRuntime.cpp?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/lib/Basic/ObjCRuntime.cpp (original) +++ cfe/trunk/lib/Basic/ObjCRuntime.cpp Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===- ObjCRuntime.cpp - Objective-C Runtime Handling -----------*- C++ -*-===// +//===- ObjCRuntime.cpp - Objective-C Runtime Handling ---------------------===// // // The LLVM Compiler Infrastructure // @@ -11,8 +11,13 @@ // target Objective-C runtime. // //===----------------------------------------------------------------------===// + #include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" +#include <cstddef> +#include <string> using namespace clang; Modified: cfe/trunk/lib/Basic/Sanitizers.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Sanitizers.cpp?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Sanitizers.cpp (original) +++ cfe/trunk/lib/Basic/Sanitizers.cpp Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===--- Sanitizers.cpp - C Language Family Language Options ----*- C++ -*-===// +//===- Sanitizers.cpp - C Language Family Language Options ----------------===// // // The LLVM Compiler Infrastructure // @@ -10,9 +10,8 @@ // This file defines the classes from Sanitizers.h // //===----------------------------------------------------------------------===// + #include "clang/Basic/Sanitizers.h" -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; Modified: cfe/trunk/lib/Basic/VirtualFileSystem.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/VirtualFileSystem.cpp?rev=328735&r1=328734&r2=328735&view=diff ============================================================================== --- cfe/trunk/lib/Basic/VirtualFileSystem.cpp (original) +++ cfe/trunk/lib/Basic/VirtualFileSystem.cpp Wed Mar 28 15:09:09 2018 @@ -1,4 +1,4 @@ -//===- VirtualFileSystem.cpp - Virtual File System Layer --------*- C++ -*-===// +//===- VirtualFileSystem.cpp - Virtual File System Layer ------------------===// // // The LLVM Compiler Infrastructure // @@ -6,30 +6,57 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// // This file implements the VirtualFileSystem interface. +// //===----------------------------------------------------------------------===// #include "clang/Basic/VirtualFileSystem.h" -#include "clang/Basic/FileManager.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Chrono.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/YAMLParser.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> #include <atomic> +#include <cassert> +#include <cstdint> +#include <iterator> +#include <limits> +#include <map> #include <memory> +#include <string> +#include <system_error> #include <utility> +#include <vector> using namespace clang; -using namespace clang::vfs; +using namespace vfs; using namespace llvm; + using llvm::sys::fs::file_status; using llvm::sys::fs::file_type; using llvm::sys::fs::perms; @@ -38,13 +65,13 @@ using llvm::sys::fs::UniqueID; Status::Status(const file_status &Status) : UID(Status.getUniqueID()), MTime(Status.getLastModificationTime()), User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()), - Type(Status.type()), Perms(Status.permissions()), IsVFSMapped(false) {} + Type(Status.type()), Perms(Status.permissions()) {} Status::Status(StringRef Name, UniqueID UID, sys::TimePoint<> MTime, uint32_t User, uint32_t Group, uint64_t Size, file_type Type, perms Perms) : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size), - Type(Type), Perms(Perms), IsVFSMapped(false) {} + Type(Type), Perms(Perms) {} Status Status::copyWithNewName(const Status &In, StringRef NewName) { return Status(NewName, In.getUniqueID(), In.getLastModificationTime(), @@ -62,28 +89,34 @@ bool Status::equivalent(const Status &Ot assert(isStatusKnown() && Other.isStatusKnown()); return getUniqueID() == Other.getUniqueID(); } + bool Status::isDirectory() const { return Type == file_type::directory_file; } + bool Status::isRegularFile() const { return Type == file_type::regular_file; } + bool Status::isOther() const { return exists() && !isRegularFile() && !isDirectory() && !isSymlink(); } + bool Status::isSymlink() const { return Type == file_type::symlink_file; } + bool Status::isStatusKnown() const { return Type != file_type::status_error; } + bool Status::exists() const { return isStatusKnown() && Type != file_type::file_not_found; } -File::~File() {} +File::~File() = default; -FileSystem::~FileSystem() {} +FileSystem::~FileSystem() = default; ErrorOr<std::unique_ptr<MemoryBuffer>> FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize, @@ -97,7 +130,7 @@ FileSystem::getBufferForFile(const llvm: std::error_code FileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { if (llvm::sys::path::is_absolute(Path)) - return std::error_code(); + return {}; auto WorkingDir = getCurrentWorkingDirectory(); if (!WorkingDir) @@ -118,6 +151,7 @@ static bool isTraversalComponent(StringR static bool pathHasTraversal(StringRef Path) { using namespace llvm::sys; + for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path))) if (isTraversalComponent(Comp)) return true; @@ -130,12 +164,15 @@ static bool pathHasTraversal(StringRef P //===-----------------------------------------------------------------------===/ namespace { + /// \brief Wrapper around a raw file descriptor. class RealFile : public File { + friend class RealFileSystem; + int FD; Status S; std::string RealName; - friend class RealFileSystem; + RealFile(int FD, StringRef NewName, StringRef NewRealPathName) : FD(FD), S(NewName, {}, {}, {}, {}, {}, llvm::sys::fs::file_type::status_error, {}), @@ -145,6 +182,7 @@ class RealFile : public File { public: ~RealFile() override; + ErrorOr<Status> status() override; ErrorOr<std::string> getName() override; ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name, @@ -153,7 +191,9 @@ public: bool IsVolatile) override; std::error_code close() override; }; -} // end anonymous namespace + +} // namespace + RealFile::~RealFile() { close(); } ErrorOr<Status> RealFile::status() { @@ -186,6 +226,7 @@ std::error_code RealFile::close() { } namespace { + /// \brief The file system according to your operating system. class RealFileSystem : public FileSystem { public: @@ -196,7 +237,8 @@ public: llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; }; -} // end anonymous namespace + +} // namespace ErrorOr<Status> RealFileSystem::status(const Twine &Path) { sys::fs::file_status RealStatus; @@ -238,8 +280,10 @@ IntrusiveRefCntPtr<FileSystem> vfs::getR } namespace { + class RealFSDirIter : public clang::vfs::detail::DirIterImpl { llvm::sys::fs::directory_iterator Iter; + public: RealFSDirIter(const Twine &Path, std::error_code &EC) : Iter(Path, EC) { if (!EC && Iter != llvm::sys::fs::directory_iterator()) { @@ -264,7 +308,8 @@ public: return EC; } }; -} + +} // namespace directory_iterator RealFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -274,6 +319,7 @@ directory_iterator RealFileSystem::dir_b //===-----------------------------------------------------------------------===/ // OverlayFileSystem implementation //===-----------------------------------------------------------------------===/ + OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) { FSList.push_back(std::move(BaseFS)); } @@ -311,17 +357,19 @@ OverlayFileSystem::getCurrentWorkingDire // All file systems are synchronized, just take the first working directory. return FSList.front()->getCurrentWorkingDirectory(); } + std::error_code OverlayFileSystem::setCurrentWorkingDirectory(const Twine &Path) { for (auto &FS : FSList) if (std::error_code EC = FS->setCurrentWorkingDirectory(Path)) return EC; - return std::error_code(); + return {}; } -clang::vfs::detail::DirIterImpl::~DirIterImpl() { } +clang::vfs::detail::DirIterImpl::~DirIterImpl() = default; namespace { + class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl { OverlayFileSystem &Overlays; std::string Path; @@ -340,7 +388,7 @@ class OverlayFSDirIterImpl : public clan if (CurrentDirIter != directory_iterator()) break; // found } - return std::error_code(); + return {}; } std::error_code incrementDirIter(bool IsFirstTime) { @@ -379,7 +427,8 @@ public: std::error_code increment() override { return incrementImpl(false); } }; -} // end anonymous namespace + +} // namespace directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -389,6 +438,7 @@ directory_iterator OverlayFileSystem::di namespace clang { namespace vfs { + namespace detail { enum InMemoryNodeKind { IME_File, IME_Directory }; @@ -402,13 +452,15 @@ class InMemoryNode { public: InMemoryNode(Status Stat, InMemoryNodeKind Kind) : Stat(std::move(Stat)), Kind(Kind) {} - virtual ~InMemoryNode() {} + virtual ~InMemoryNode() = default; + const Status &getStatus() const { return Stat; } InMemoryNodeKind getKind() const { return Kind; } virtual std::string toString(unsigned Indent) const = 0; }; namespace { + class InMemoryFile : public InMemoryNode { std::unique_ptr<llvm::MemoryBuffer> Buffer; @@ -417,9 +469,11 @@ public: : InMemoryNode(std::move(Stat), IME_File), Buffer(std::move(Buffer)) {} llvm::MemoryBuffer *getBuffer() { return Buffer.get(); } + std::string toString(unsigned Indent) const override { return (std::string(Indent, ' ') + getStatus().getName() + "\n").str(); } + static bool classof(const InMemoryNode *N) { return N->getKind() == IME_File; } @@ -433,6 +487,7 @@ public: explicit InMemoryFileAdaptor(InMemoryFile &Node) : Node(Node) {} llvm::ErrorOr<Status> status() override { return Node.getStatus(); } + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override { @@ -440,9 +495,11 @@ public: return llvm::MemoryBuffer::getMemBuffer( Buf->getBuffer(), Buf->getBufferIdentifier(), RequiresNullTerminator); } - std::error_code close() override { return std::error_code(); } + + std::error_code close() override { return {}; } }; -} // end anonymous namespace + +} // namespace class InMemoryDirectory : public InMemoryNode { std::map<std::string, std::unique_ptr<InMemoryNode>> Entries; @@ -450,34 +507,38 @@ class InMemoryDirectory : public InMemor public: InMemoryDirectory(Status Stat) : InMemoryNode(std::move(Stat), IME_Directory) {} + InMemoryNode *getChild(StringRef Name) { auto I = Entries.find(Name); if (I != Entries.end()) return I->second.get(); return nullptr; } + InMemoryNode *addChild(StringRef Name, std::unique_ptr<InMemoryNode> Child) { return Entries.insert(make_pair(Name, std::move(Child))) .first->second.get(); } - typedef decltype(Entries)::const_iterator const_iterator; + using const_iterator = decltype(Entries)::const_iterator; + const_iterator begin() const { return Entries.begin(); } const_iterator end() const { return Entries.end(); } std::string toString(unsigned Indent) const override { std::string Result = (std::string(Indent, ' ') + getStatus().getName() + "\n").str(); - for (const auto &Entry : Entries) { + for (const auto &Entry : Entries) Result += Entry.second->toString(Indent + 2); - } return Result; } + static bool classof(const InMemoryNode *N) { return N->getKind() == IME_Directory; } }; -} + +} // namespace detail InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths) : Root(new detail::InMemoryDirectory( @@ -486,7 +547,7 @@ InMemoryFileSystem::InMemoryFileSystem(b llvm::sys::fs::perms::all_all))), UseNormalizedPaths(UseNormalizedPaths) {} -InMemoryFileSystem::~InMemoryFileSystem() {} +InMemoryFileSystem::~InMemoryFileSystem() = default; std::string InMemoryFileSystem::toString() const { return Root->toString(/*Indent=*/0); @@ -645,13 +706,15 @@ InMemoryFileSystem::openFileForRead(cons } namespace { + /// Adaptor from InMemoryDir::iterator to directory_iterator. class InMemoryDirIterator : public clang::vfs::detail::DirIterImpl { detail::InMemoryDirectory::const_iterator I; detail::InMemoryDirectory::const_iterator E; public: - InMemoryDirIterator() {} + InMemoryDirIterator() = default; + explicit InMemoryDirIterator(detail::InMemoryDirectory &Dir) : I(Dir.begin()), E(Dir.end()) { if (I != E) @@ -663,10 +726,11 @@ public: // When we're at the end, make CurrentEntry invalid and DirIterImpl will do // the rest. CurrentEntry = I != E ? I->second->getStatus() : Status(); - return std::error_code(); + return {}; } }; -} // end anonymous namespace + +} // namespace directory_iterator InMemoryFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -697,11 +761,12 @@ std::error_code InMemoryFileSystem::setC if (!Path.empty()) WorkingDirectory = Path.str(); - return std::error_code(); -} -} + return {}; } +} // namespace vfs +} // namespace clang + //===-----------------------------------------------------------------------===/ // RedirectingFileSystem implementation //===-----------------------------------------------------------------------===/ @@ -719,8 +784,9 @@ class Entry { std::string Name; public: - virtual ~Entry(); Entry(EntryKind K, StringRef Name) : Kind(K), Name(Name) {} + virtual ~Entry() = default; + StringRef getName() const { return Name; } EntryKind getKind() const { return Kind; } }; @@ -737,14 +803,20 @@ public: S(std::move(S)) {} RedirectingDirectoryEntry(StringRef Name, Status S) : Entry(EK_Directory, Name), S(std::move(S)) {} + Status getStatus() { return S; } + void addContent(std::unique_ptr<Entry> Content) { Contents.push_back(std::move(Content)); } + Entry *getLastContent() const { return Contents.back().get(); } - typedef decltype(Contents)::iterator iterator; + + using iterator = decltype(Contents)::iterator; + iterator contents_begin() { return Contents.begin(); } iterator contents_end() { return Contents.end(); } + static bool classof(const Entry *E) { return E->getKind() == EK_Directory; } }; @@ -755,21 +827,27 @@ public: NK_External, NK_Virtual }; + private: std::string ExternalContentsPath; NameKind UseName; + public: RedirectingFileEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName) : Entry(EK_File, Name), ExternalContentsPath(ExternalContentsPath), UseName(UseName) {} + StringRef getExternalContentsPath() const { return ExternalContentsPath; } + /// \brief whether to use the external path as the name for this file. bool useExternalName(bool GlobalUseExternalName) const { return UseName == NK_NotSet ? GlobalUseExternalName : (UseName == NK_External); } + NameKind getUseName() const { return UseName; } + static bool classof(const Entry *E) { return E->getKind() == EK_File; } }; @@ -785,6 +863,7 @@ public: RedirectingDirectoryEntry::iterator Begin, RedirectingDirectoryEntry::iterator End, std::error_code &EC); + std::error_code increment() override; }; @@ -844,10 +923,14 @@ public: /// /path/to/file). However, any directory that contains more than one child /// must be uniquely represented by a directory entry. class RedirectingFileSystem : public vfs::FileSystem { + friend class RedirectingFileSystemParser; + /// The root(s) of the virtual file system. std::vector<std::unique_ptr<Entry>> Roots; + /// \brief The file system to use for external references. IntrusiveRefCntPtr<FileSystem> ExternalFS; + /// If IsRelativeOverlay is set, this represents the directory /// path that should be prefixed to each 'external-contents' entry /// when reading from YAML files. @@ -888,8 +971,6 @@ class RedirectingFileSystem : public vfs true; #endif - friend class RedirectingFileSystemParser; - private: RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS) : ExternalFS(std::move(ExternalFS)) {} @@ -919,6 +1000,7 @@ public: llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { return ExternalFS->getCurrentWorkingDirectory(); } + std::error_code setCurrentWorkingDirectory(const Twine &Path) override { return ExternalFS->setCurrentWorkingDirectory(Path); } @@ -927,17 +1009,17 @@ public: ErrorOr<Entry *> E = lookupPath(Dir); if (!E) { EC = E.getError(); - return directory_iterator(); + return {}; } ErrorOr<Status> S = status(Dir, *E); if (!S) { EC = S.getError(); - return directory_iterator(); + return {}; } if (!S->isDirectory()) { EC = std::error_code(static_cast<int>(errc::not_a_directory), std::system_category()); - return directory_iterator(); + return {}; } auto *D = cast<RedirectingDirectoryEntry>(*E); @@ -959,7 +1041,7 @@ public: #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void dump() const { - for (const std::unique_ptr<Entry> &Root : Roots) + for (const auto &Root : Roots) dumpEntry(Root.get()); } @@ -979,7 +1061,6 @@ LLVM_DUMP_METHOD void dumpEntry(Entry *E } } #endif - }; /// \brief A helper class to hold the common YAML parsing state. @@ -993,7 +1074,8 @@ class RedirectingFileSystemParser { // false on error bool parseScalarString(yaml::Node *N, StringRef &Result, SmallVectorImpl<char> &Storage) { - yaml::ScalarNode *S = dyn_cast<yaml::ScalarNode>(N); + const auto *S = dyn_cast<yaml::ScalarNode>(N); + if (!S) { error(N, "expected string"); return false; @@ -1024,11 +1106,13 @@ class RedirectingFileSystemParser { } struct KeyStatus { - KeyStatus(bool Required=false) : Required(Required), Seen(false) {} bool Required; - bool Seen; + bool Seen = false; + + KeyStatus(bool Required = false) : Required(Required) {} }; - typedef std::pair<StringRef, KeyStatus> KeyStatusPair; + + using KeyStatusPair = std::pair<StringRef, KeyStatus>; // false on error bool checkDuplicateOrUnknownKey(yaml::Node *KeyNode, StringRef Key, @@ -1048,11 +1132,9 @@ class RedirectingFileSystemParser { // false on error bool checkMissingKeys(yaml::Node *Obj, DenseMap<StringRef, KeyStatus> &Keys) { - for (DenseMap<StringRef, KeyStatus>::iterator I = Keys.begin(), - E = Keys.end(); - I != E; ++I) { - if (I->second.Required && !I->second.Seen) { - error(Obj, Twine("missing key '") + I->first + "'"); + for (const auto &I : Keys) { + if (I.second.Required && !I.second.Seen) { + error(Obj, Twine("missing key '") + I.first + "'"); return false; } } @@ -1062,7 +1144,7 @@ class RedirectingFileSystemParser { Entry *lookupOrCreateEntry(RedirectingFileSystem *FS, StringRef Name, Entry *ParentEntry = nullptr) { if (!ParentEntry) { // Look for a existent root - for (const std::unique_ptr<Entry> &Root : FS->Roots) { + for (const auto &Root : FS->Roots) { if (Name.equals(Root->getName())) { ParentEntry = Root.get(); return ParentEntry; @@ -1125,7 +1207,7 @@ class RedirectingFileSystemParser { } std::unique_ptr<Entry> parseEntry(yaml::Node *N, RedirectingFileSystem *FS) { - yaml::MappingNode *M = dyn_cast<yaml::MappingNode>(N); + auto *M = dyn_cast<yaml::MappingNode>(N); if (!M) { error(N, "expected mapping node for file or directory entry"); return nullptr; @@ -1148,21 +1230,20 @@ class RedirectingFileSystemParser { auto UseExternalName = RedirectingFileEntry::NK_NotSet; EntryKind Kind; - for (yaml::MappingNode::iterator I = M->begin(), E = M->end(); I != E; - ++I) { + for (auto &I : *M) { StringRef Key; // Reuse the buffer for key and value, since we don't look at key after // parsing value. SmallString<256> Buffer; - if (!parseScalarString(I->getKey(), Key, Buffer)) + if (!parseScalarString(I.getKey(), Key, Buffer)) return nullptr; - if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys)) + if (!checkDuplicateOrUnknownKey(I.getKey(), Key, Keys)) return nullptr; StringRef Value; if (Key == "name") { - if (!parseScalarString(I->getValue(), Value, Buffer)) + if (!parseScalarString(I.getValue(), Value, Buffer)) return nullptr; if (FS->UseCanonicalizedPaths) { @@ -1176,47 +1257,44 @@ class RedirectingFileSystemParser { Name = Value; } } else if (Key == "type") { - if (!parseScalarString(I->getValue(), Value, Buffer)) + if (!parseScalarString(I.getValue(), Value, Buffer)) return nullptr; if (Value == "file") Kind = EK_File; else if (Value == "directory") Kind = EK_Directory; else { - error(I->getValue(), "unknown value for 'type'"); + error(I.getValue(), "unknown value for 'type'"); return nullptr; } } else if (Key == "contents") { if (HasContents) { - error(I->getKey(), + error(I.getKey(), "entry already has 'contents' or 'external-contents'"); return nullptr; } HasContents = true; - yaml::SequenceNode *Contents = - dyn_cast<yaml::SequenceNode>(I->getValue()); + auto *Contents = dyn_cast<yaml::SequenceNode>(I.getValue()); if (!Contents) { // FIXME: this is only for directories, what about files? - error(I->getValue(), "expected array"); + error(I.getValue(), "expected array"); return nullptr; } - for (yaml::SequenceNode::iterator I = Contents->begin(), - E = Contents->end(); - I != E; ++I) { - if (std::unique_ptr<Entry> E = parseEntry(&*I, FS)) + for (auto &I : *Contents) { + if (std::unique_ptr<Entry> E = parseEntry(&I, FS)) EntryArrayContents.push_back(std::move(E)); else return nullptr; } } else if (Key == "external-contents") { if (HasContents) { - error(I->getKey(), + error(I.getKey(), "entry already has 'contents' or 'external-contents'"); return nullptr; } HasContents = true; - if (!parseScalarString(I->getValue(), Value, Buffer)) + if (!parseScalarString(I.getValue(), Value, Buffer)) return nullptr; SmallString<256> FullPath; @@ -1238,7 +1316,7 @@ class RedirectingFileSystemParser { ExternalContentsPath = FullPath.str(); } else if (Key == "use-external-name") { bool Val; - if (!parseScalarBool(I->getValue(), Val)) + if (!parseScalarBool(I.getValue(), Val)) return nullptr; UseExternalName = Val ? RedirectingFileEntry::NK_External : RedirectingFileEntry::NK_Virtual; @@ -1311,7 +1389,7 @@ public: // false on error bool parse(yaml::Node *Root, RedirectingFileSystem *FS) { - yaml::MappingNode *Top = dyn_cast<yaml::MappingNode>(Root); + auto *Top = dyn_cast<yaml::MappingNode>(Root); if (!Top) { error(Root, "expected mapping node"); return false; @@ -1330,26 +1408,24 @@ public: std::vector<std::unique_ptr<Entry>> RootEntries; // Parse configuration and 'roots' - for (yaml::MappingNode::iterator I = Top->begin(), E = Top->end(); I != E; - ++I) { + for (auto &I : *Top) { SmallString<10> KeyBuffer; StringRef Key; - if (!parseScalarString(I->getKey(), Key, KeyBuffer)) + if (!parseScalarString(I.getKey(), Key, KeyBuffer)) return false; - if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys)) + if (!checkDuplicateOrUnknownKey(I.getKey(), Key, Keys)) return false; if (Key == "roots") { - yaml::SequenceNode *Roots = dyn_cast<yaml::SequenceNode>(I->getValue()); + auto *Roots = dyn_cast<yaml::SequenceNode>(I.getValue()); if (!Roots) { - error(I->getValue(), "expected array"); + error(I.getValue(), "expected array"); return false; } - for (yaml::SequenceNode::iterator I = Roots->begin(), E = Roots->end(); - I != E; ++I) { - if (std::unique_ptr<Entry> E = parseEntry(&*I, FS)) + for (auto &I : *Roots) { + if (std::unique_ptr<Entry> E = parseEntry(&I, FS)) RootEntries.push_back(std::move(E)); else return false; @@ -1357,32 +1433,32 @@ public: } else if (Key == "version") { StringRef VersionString; SmallString<4> Storage; - if (!parseScalarString(I->getValue(), VersionString, Storage)) + if (!parseScalarString(I.getValue(), VersionString, Storage)) return false; int Version; if (VersionString.getAsInteger<int>(10, Version)) { - error(I->getValue(), "expected integer"); + error(I.getValue(), "expected integer"); return false; } if (Version < 0) { - error(I->getValue(), "invalid version number"); + error(I.getValue(), "invalid version number"); return false; } if (Version != 0) { - error(I->getValue(), "version mismatch, expected 0"); + error(I.getValue(), "version mismatch, expected 0"); return false; } } else if (Key == "case-sensitive") { - if (!parseScalarBool(I->getValue(), FS->CaseSensitive)) + if (!parseScalarBool(I.getValue(), FS->CaseSensitive)) return false; } else if (Key == "overlay-relative") { - if (!parseScalarBool(I->getValue(), FS->IsRelativeOverlay)) + if (!parseScalarBool(I.getValue(), FS->IsRelativeOverlay)) return false; } else if (Key == "use-external-names") { - if (!parseScalarBool(I->getValue(), FS->UseExternalNames)) + if (!parseScalarBool(I.getValue(), FS->UseExternalNames)) return false; } else if (Key == "ignore-non-existent-contents") { - if (!parseScalarBool(I->getValue(), FS->IgnoreNonExistentContents)) + if (!parseScalarBool(I.getValue(), FS->IgnoreNonExistentContents)) return false; } else { llvm_unreachable("key missing from Keys"); @@ -1398,22 +1474,20 @@ public: // Now that we sucessefully parsed the YAML file, canonicalize the internal // representation to a proper directory tree so that we can search faster // inside the VFS. - for (std::unique_ptr<Entry> &E : RootEntries) + for (auto &E : RootEntries) uniqueOverlayTree(FS, E.get()); return true; } }; -} // end of anonymous namespace -Entry::~Entry() = default; +} // namespace RedirectingFileSystem * RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS) { - SourceMgr SM; yaml::Stream Stream(Buffer->getMemBufferRef(), SM); @@ -1473,7 +1547,7 @@ ErrorOr<Entry *> RedirectingFileSystem:: sys::path::const_iterator Start = sys::path::begin(Path); sys::path::const_iterator End = sys::path::end(Path); - for (const std::unique_ptr<Entry> &Root : Roots) { + for (const auto &Root : Roots) { ErrorOr<Entry *> Result = lookupPath(Start, End, Root.get()); if (Result || Result.getError() != llvm::errc::no_such_file_or_directory) return Result; @@ -1557,6 +1631,7 @@ ErrorOr<Status> RedirectingFileSystem::s } namespace { + /// Provide a file wrapper with an overriden status. class FileWithFixedStatus : public File { std::unique_ptr<File> InnerFile; @@ -1568,14 +1643,17 @@ public: ErrorOr<Status> status() override { return S; } ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> + getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override { return InnerFile->getBuffer(Name, FileSize, RequiresNullTerminator, IsVolatile); } + std::error_code close() override { return InnerFile->close(); } }; -} // end anonymous namespace + +} // namespace ErrorOr<std::unique_ptr<File>> RedirectingFileSystem::openFileForRead(const Twine &Path) { @@ -1670,11 +1748,13 @@ void YAMLVFSWriter::addFileMapping(Strin } namespace { + class JSONWriter { llvm::raw_ostream &OS; SmallVector<StringRef, 16> DirStack; - inline unsigned getDirIndent() { return 4 * DirStack.size(); } - inline unsigned getFileIndent() { return 4 * (DirStack.size() + 1); } + + unsigned getDirIndent() { return 4 * DirStack.size(); } + unsigned getFileIndent() { return 4 * (DirStack.size() + 1); } bool containedIn(StringRef Parent, StringRef Path); StringRef containedPart(StringRef Parent, StringRef Path); void startDirectory(StringRef Path); @@ -1683,14 +1763,17 @@ class JSONWriter { public: JSONWriter(llvm::raw_ostream &OS) : OS(OS) {} + void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, Optional<bool> IgnoreNonExistentContents, StringRef OverlayDir); }; -} + +} // namespace bool JSONWriter::containedIn(StringRef Parent, StringRef Path) { using namespace llvm::sys; + // Compare each path component. auto IParent = path::begin(Parent), EParent = path::end(Parent); for (auto IChild = path::begin(Path), EChild = path::end(Path); @@ -1868,7 +1951,7 @@ std::error_code VFSFromYamlDirIterImpl:: if (Current == End) CurrentEntry = Status(); - return std::error_code(); + return {}; } vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits