mirror of https://github.com/microsoft/clang.git
[Basic] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328735 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c4bfd75d78
commit
4654818441
|
@ -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(unsigned TargetAS) {
|
|||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_BASIC_ADDRESSSPACES_H
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, Linkage L2) {
|
|||
return L1 < L2 ? L1 : L2;
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_LINKAGE_H
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 getPPTransparentSanitizers() {
|
|||
SanitizerKind::Nullability | SanitizerKind::Undefined;
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_BASIC_SANITIZERS_H
|
||||
|
|
|
@ -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> getRealFileSystem();
|
|||
/// 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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 &Other) const {
|
|||
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::Twine &Name, int64_t FileSize,
|
|||
|
||||
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(StringRef Component) {
|
|||
|
||||
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 Path) {
|
|||
//===-----------------------------------------------------------------------===/
|
||||
|
||||
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::getRealFileSystem() {
|
|||
}
|
||||
|
||||
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_begin(const Twine &Dir,
|
|||
//===-----------------------------------------------------------------------===/
|
||||
// OverlayFileSystem implementation
|
||||
//===-----------------------------------------------------------------------===/
|
||||
|
||||
OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) {
|
||||
FSList.push_back(std::move(BaseFS));
|
||||
}
|
||||
|
@ -311,17 +357,19 @@ OverlayFileSystem::getCurrentWorkingDirectory() const {
|
|||
// 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 clang::vfs::detail::DirIterImpl {
|
|||
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::dir_begin(const Twine &Dir,
|
|||
|
||||
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 InMemoryNode {
|
|||
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(bool UseNormalizedPaths)
|
|||
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(const Twine &Path) {
|
|||
}
|
||||
|
||||
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::setCurrentWorkingDirectory(const Twine &P) {
|
|||
|
||||
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::FileSystem {
|
|||
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, int NumSpaces = 0) const {
|
|||
}
|
||||
}
|
||||
#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::lookupPath(const Twine &Path_) {
|
|||
|
||||
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::status(const Twine &Path) {
|
|||
}
|
||||
|
||||
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(StringRef VirtualPath, StringRef RealPath) {
|
|||
}
|
||||
|
||||
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::increment() {
|
|||
|
||||
if (Current == End)
|
||||
CurrentEntry = Status();
|
||||
return std::error_code();
|
||||
return {};
|
||||
}
|
||||
|
||||
vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_,
|
||||
|
|
Loading…
Reference in New Issue