summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/VirtualFileSystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Basic/VirtualFileSystem.cpp')
-rw-r--r--clang/lib/Basic/VirtualFileSystem.cpp61
1 files changed, 46 insertions, 15 deletions
diff --git a/clang/lib/Basic/VirtualFileSystem.cpp b/clang/lib/Basic/VirtualFileSystem.cpp
index 539cbb74097..f6d88c1860d 100644
--- a/clang/lib/Basic/VirtualFileSystem.cpp
+++ b/clang/lib/Basic/VirtualFileSystem.cpp
@@ -35,8 +35,8 @@ Status::Status(const file_status &Status)
Status::Status(StringRef Name, StringRef ExternalName, UniqueID UID,
sys::TimeValue MTime, uint32_t User, uint32_t Group,
uint64_t Size, file_type Type, perms Perms)
- : Name(Name), ExternalName(ExternalName), UID(UID), MTime(MTime),
- User(User), Group(Group), Size(Size), Type(Type), Perms(Perms) {}
+ : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size),
+ Type(Type), Perms(Perms) {}
bool Status::equivalent(const Status &Other) const {
return getUniqueID() == Other.getUniqueID();
@@ -145,7 +145,6 @@ ErrorOr<Status> RealFileSystem::status(const Twine &Path) {
return EC;
Status Result(RealStatus);
Result.setName(Path.str());
- Result.setExternalName(Path.str());
return Result;
}
@@ -253,12 +252,22 @@ public:
};
class FileEntry : public Entry {
+public:
+ enum NameKind {
+ NK_NotSet,
+ NK_External,
+ NK_Virtual
+ };
+private:
std::string ExternalContentsPath;
-
+ NameKind UseName;
public:
- FileEntry(StringRef Name, StringRef ExternalContentsPath)
- : Entry(EK_File, Name), ExternalContentsPath(ExternalContentsPath) {}
+ FileEntry(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.
+ NameKind useName() const { return UseName; }
static bool classof(const Entry *E) { return E->getKind() == EK_File; }
};
@@ -280,6 +289,7 @@ public:
///
/// All configuration options are optional.
/// 'case-sensitive': <boolean, default=true>
+/// 'use-external-names': <boolean, default=true>
///
/// Virtual directories are represented as
/// \verbatim
@@ -304,6 +314,7 @@ public:
/// {
/// 'type': 'file',
/// 'name': <string>,
+/// 'use-external-name': <boolean> # Optional
/// 'external-contents': <path to external file>)
/// }
/// \endverbatim
@@ -324,14 +335,18 @@ class VFSFromYAML : public vfs::FileSystem {
/// \brief Whether to perform case-sensitive comparisons.
///
/// Currently, case-insensitive matching only works correctly with ASCII.
- bool CaseSensitive; ///< Whether to perform case-sensitive comparisons.
+ bool CaseSensitive;
+
+ /// \brief Whether to use to use the value of 'external-contents' for the
+ /// names of files. This global value is overridable on a per-file basis.
+ bool UseExternalNames;
/// @}
friend class VFSFromYAMLParser;
private:
VFSFromYAML(IntrusiveRefCntPtr<FileSystem> ExternalFS)
- : ExternalFS(ExternalFS), CaseSensitive(true) {}
+ : ExternalFS(ExternalFS), CaseSensitive(true), UseExternalNames(true) {}
/// \brief Looks up \p Path in \c Roots.
ErrorOr<Entry *> lookupPath(const Twine &Path);
@@ -446,7 +461,8 @@ class VFSFromYAMLParser {
KeyStatusPair("name", true),
KeyStatusPair("type", true),
KeyStatusPair("contents", false),
- KeyStatusPair("external-contents", false)
+ KeyStatusPair("external-contents", false),
+ KeyStatusPair("use-external-name", false),
};
DenseMap<StringRef, KeyStatus> Keys(
@@ -456,6 +472,7 @@ class VFSFromYAMLParser {
std::vector<Entry *> EntryArrayContents;
std::string ExternalContentsPath;
std::string Name;
+ FileEntry::NameKind UseExternalName = FileEntry::NK_NotSet;
EntryKind Kind;
for (yaml::MappingNode::iterator I = M->begin(), E = M->end(); I != E;
@@ -519,6 +536,11 @@ class VFSFromYAMLParser {
if (!parseScalarString(I->getValue(), Value, Buffer))
return NULL;
ExternalContentsPath = Value;
+ } else if (Key == "use-external-name") {
+ bool Val;
+ if (!parseScalarBool(I->getValue(), Val))
+ return NULL;
+ UseExternalName = Val ? FileEntry::NK_External : FileEntry::NK_Virtual;
} else {
llvm_unreachable("key missing from Keys");
}
@@ -535,6 +557,12 @@ class VFSFromYAMLParser {
if (!checkMissingKeys(N, Keys))
return NULL;
+ // check invalid configuration
+ if (Kind == EK_Directory && UseExternalName != FileEntry::NK_NotSet) {
+ error(N, "'use-external-name' is not supported for directories");
+ return NULL;
+ }
+
// Remove trailing slash(es)
StringRef Trimmed(Name);
while (Trimmed.size() > 1 && sys::path::is_separator(Trimmed.back()))
@@ -545,7 +573,8 @@ class VFSFromYAMLParser {
Entry *Result = 0;
switch (Kind) {
case EK_File:
- Result = new FileEntry(LastComponent, llvm_move(ExternalContentsPath));
+ Result = new FileEntry(LastComponent, llvm_move(ExternalContentsPath),
+ UseExternalName);
break;
case EK_Directory:
Result = new DirectoryEntry(LastComponent, llvm_move(EntryArrayContents),
@@ -583,6 +612,7 @@ public:
KeyStatusPair Fields[] = {
KeyStatusPair("version", true),
KeyStatusPair("case-sensitive", false),
+ KeyStatusPair("use-external-names", false),
KeyStatusPair("roots", true),
};
@@ -635,6 +665,9 @@ public:
} else if (Key == "case-sensitive") {
if (!parseScalarBool(I->getValue(), FS->CaseSensitive))
return false;
+ } else if (Key == "use-external-names") {
+ if (!parseScalarBool(I->getValue(), FS->UseExternalNames))
+ return false;
} else {
llvm_unreachable("key missing from Keys");
}
@@ -736,17 +769,15 @@ ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
std::string PathStr(Path.str());
if (FileEntry *F = dyn_cast<FileEntry>(*Result)) {
ErrorOr<Status> S = ExternalFS->status(F->getExternalContentsPath());
- if (S) {
- assert(S->getName() == S->getExternalName() &&
- S->getName() == F->getExternalContentsPath());
+ assert(!S || S->getName() == F->getExternalContentsPath());
+ if (S && (F->useName() == FileEntry::NK_Virtual ||
+ (F->useName() == FileEntry::NK_NotSet && !UseExternalNames)))
S->setName(PathStr);
- }
return S;
} else { // directory
DirectoryEntry *DE = cast<DirectoryEntry>(*Result);
Status S = DE->getStatus();
S.setName(PathStr);
- S.setExternalName(PathStr);
return S;
}
}
OpenPOWER on IntegriCloud