haowei updated this revision to Diff 474115.
haowei marked 2 inline comments as done.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137473/new/

https://reviews.llvm.org/D137473

Files:
  clang/test/VFS/Inputs/root-relative-overlay.yaml
  clang/test/VFS/relative-path.c
  llvm/include/llvm/Support/VirtualFileSystem.h
  llvm/lib/Support/VirtualFileSystem.cpp

Index: llvm/lib/Support/VirtualFileSystem.cpp
===================================================================
--- llvm/lib/Support/VirtualFileSystem.cpp
+++ llvm/lib/Support/VirtualFileSystem.cpp
@@ -1482,12 +1482,12 @@
   return Combined;
 }
 
-void RedirectingFileSystem::setExternalContentsPrefixDir(StringRef PrefixDir) {
-  ExternalContentsPrefixDir = PrefixDir.str();
+void RedirectingFileSystem::setOverlayFileDir(StringRef Dir) {
+  OverlayFileDir = Dir.str();
 }
 
-StringRef RedirectingFileSystem::getExternalContentsPrefixDir() const {
-  return ExternalContentsPrefixDir;
+StringRef RedirectingFileSystem::getOverlayFileDir() const {
+  return OverlayFileDir;
 }
 
 void RedirectingFileSystem::setFallthrough(bool Fallthrough) {
@@ -1621,6 +1621,20 @@
     return None;
   }
 
+  Optional<RedirectingFileSystem::RootRelativeKind>
+  parseRootRelativeKind(yaml::Node *N) {
+    SmallString<12> Storage;
+    StringRef Value;
+    if (!parseScalarString(N, Value, Storage))
+      return None;
+    if (Value.equals_insensitive("cwd")) {
+      return RedirectingFileSystem::RootRelativeKind::CWD;
+    } else if (Value.equals_insensitive("overlay-dir")) {
+      return RedirectingFileSystem::RootRelativeKind::OverlayDir;
+    }
+    return None;
+  }
+
   struct KeyStatus {
     bool Required;
     bool Seen = false;
@@ -1828,7 +1842,7 @@
 
         SmallString<256> FullPath;
         if (FS->IsRelativeOverlay) {
-          FullPath = FS->getExternalContentsPrefixDir();
+          FullPath = FS->getOverlayFileDir();
           assert(!FullPath.empty() &&
                  "External contents prefix directory must exist");
           llvm::sys::path::append(FullPath, Value);
@@ -1884,6 +1898,15 @@
       } else if (sys::path::is_absolute(Name,
                                         sys::path::Style::windows_backslash)) {
         path_style = sys::path::Style::windows_backslash;
+      } else if (FS->RootRelative ==
+                 RedirectingFileSystem::RootRelativeKind::OverlayDir) {
+        SmallString<256> FullPath = FS->getOverlayFileDir();
+        assert(!FullPath.empty() && "Overlay file directory must exist");
+        sys::fs::make_absolute(FS->getOverlayFileDir(), Name);
+        Name = canonicalize(Name);
+        path_style = sys::path::is_absolute(Name, sys::path::Style::posix)
+                         ? sys::path::Style::posix
+                         : sys::path::Style::windows_backslash;
       } else {
         // Relative VFS root entries are made absolute to the current working
         // directory, then we can determine the path style from that.
@@ -1962,6 +1985,7 @@
         KeyStatusPair("version", true),
         KeyStatusPair("case-sensitive", false),
         KeyStatusPair("use-external-names", false),
+        KeyStatusPair("root-relative", false),
         KeyStatusPair("overlay-relative", false),
         KeyStatusPair("fallthrough", false),
         KeyStatusPair("redirecting-with", false),
@@ -2051,6 +2075,13 @@
           error(I.getValue(), "expected valid redirect kind");
           return false;
         }
+      } else if (Key == "root-relative") {
+        if (auto Kind = parseRootRelativeKind(I.getValue())) {
+          FS->RootRelative = *Kind;
+        } else {
+          error(I.getValue(), "expected valid root-relative kind");
+          return false;
+        }
       } else {
         llvm_unreachable("key missing from Keys");
       }
@@ -2100,13 +2131,13 @@
     // Example:
     //    -ivfsoverlay dummy.cache/vfs/vfs.yaml
     // yields:
-    //  FS->ExternalContentsPrefixDir => /<absolute_path_to>/dummy.cache/vfs
+    //  FS->YAMLFileDir => /<absolute_path_to>/dummy.cache/vfs
     //
     SmallString<256> OverlayAbsDir = sys::path::parent_path(YAMLFilePath);
     std::error_code EC = llvm::sys::fs::make_absolute(OverlayAbsDir);
     assert(!EC && "Overlay dir final path must be absolute");
     (void)EC;
-    FS->setExternalContentsPrefixDir(OverlayAbsDir);
+    FS->setOverlayFileDir(OverlayAbsDir);
   }
 
   if (!P.parse(Root, FS.get()))
Index: llvm/include/llvm/Support/VirtualFileSystem.h
===================================================================
--- llvm/include/llvm/Support/VirtualFileSystem.h
+++ llvm/include/llvm/Support/VirtualFileSystem.h
@@ -651,17 +651,28 @@
 /// \endverbatim
 ///
 /// The roots may be absolute or relative. If relative they will be made
-/// absolute against the current working directory.
+/// absolute against either current working directory or the directory where
+/// the Overlay YAML file is located, depending on the 'root-relative'
+/// configuration.
 ///
 /// All configuration options are optional.
 ///   'case-sensitive': <boolean, default=(true for Posix, false for Windows)>
 ///   'use-external-names': <boolean, default=true>
+///   'root-relative': <string, one of 'cwd' or 'overlay-dir', default='cwd'>
 ///   'overlay-relative': <boolean, default=false>
 ///   'fallthrough': <boolean, default=true, deprecated - use 'redirecting-with'
 ///                   instead>
 ///   'redirecting-with': <string, one of 'fallthrough', 'fallback', or
 ///                        'redirect-only', default='fallthrough'>
 ///
+/// To clarify, 'root-relative' option will prepend the current working
+/// directory, or the overlay directory to the 'roots->name' field only if
+/// 'roots->name' is a relative path. On the other hand, when 'overlay-relative'
+/// is set to 'true', external paths will always be prepended with the overlay
+/// directory, even if external paths are not relative paths. The
+/// 'root-relative' option has no interaction with the 'overlay-relative'
+/// option.
+///
 /// Virtual directories that list their contents are represented as
 /// \verbatim
 /// {
@@ -745,6 +756,15 @@
     RedirectOnly
   };
 
+  /// The type of relative path used by Roots.
+  enum class RootRelativeKind {
+    /// The roots are relative to the current working directory.
+    CWD,
+    /// The roots are relative to the directory where the Overlay YAML file
+    // locates.
+    OverlayDir
+  };
+
   /// A single file or directory in the VFS.
   class Entry {
     EntryKind Kind;
@@ -910,10 +930,11 @@
   /// 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.
-  std::string ExternalContentsPrefixDir;
+  /// This represents the directory path that the YAML file is located.
+  /// This will be prefixed to each 'external-contents' if IsRelativeOverlay
+  /// is set. This will also be prefixed to each 'roots->name' if RootRelative
+  /// is set to RootRelativeKind::OverlayDir and the path is relative.
+  std::string OverlayFileDir;
 
   /// @name Configuration
   /// @{
@@ -923,7 +944,7 @@
   /// Currently, case-insensitive matching only works correctly with ASCII.
   bool CaseSensitive = is_style_posix(sys::path::Style::native);
 
-  /// IsRelativeOverlay marks whether a ExternalContentsPrefixDir path must
+  /// IsRelativeOverlay marks whether a OverlayFileDir path must
   /// be prefixed in every 'external-contents' when reading from YAML files.
   bool IsRelativeOverlay = false;
 
@@ -934,6 +955,10 @@
   /// Determines the lookups to perform, as well as their order. See
   /// \c RedirectKind for details.
   RedirectKind Redirection = RedirectKind::Fallthrough;
+
+  /// Determine the prefix directory if the roots are relative paths. See
+  /// \c RootRelativeKind for details.
+  RootRelativeKind RootRelative = RootRelativeKind::CWD;
   /// @}
 
   RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS);
@@ -984,9 +1009,9 @@
 
   directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
 
-  void setExternalContentsPrefixDir(StringRef PrefixDir);
+  void setOverlayFileDir(StringRef PrefixDir);
 
-  StringRef getExternalContentsPrefixDir() const;
+  StringRef getOverlayFileDir() const;
 
   /// Sets the redirection kind to \c Fallthrough if true or \c RedirectOnly
   /// otherwise. Will removed in the future, use \c setRedirection instead.
Index: clang/test/VFS/relative-path.c
===================================================================
--- clang/test/VFS/relative-path.c
+++ clang/test/VFS/relative-path.c
@@ -3,6 +3,13 @@
 // RUN: sed -e "s@INPUT_DIR@%{/S:regex_replacement}/Inputs@g" -e "s@OUT_DIR@%{/t:regex_replacement}@g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 // RUN: %clang_cc1 -Werror -I . -ivfsoverlay %t.yaml -fsyntax-only %s
 
+// RUN: cp %S/Inputs/actual_header.h %t/actual_header.h
+// RUN: sed -e "s@OVERLAY_DIR@true@g" -e "s@EXTERNAL_DIR@.@g" %S/Inputs/root-relative-overlay.yaml > %t/root-relative-overlay.yaml
+// RUN: %clang_cc1 -Werror -I %t -ivfsoverlay %t/root-relative-overlay.yaml -fsyntax-only %s
+
+// RUN: sed -e "s@OVERLAY_DIR@false@g" -e "s@EXTERNAL_DIR@%{/t:regex_replacement}@g" %S/Inputs/root-relative-overlay.yaml > %t/root-relative-overlay2.yaml
+// RUN: %clang_cc1 -Werror -I %t -ivfsoverlay %t/root-relative-overlay2.yaml -fsyntax-only %s
+
 #include "not_real.h"
 
 void foo(void) {
Index: clang/test/VFS/Inputs/root-relative-overlay.yaml
===================================================================
--- /dev/null
+++ clang/test/VFS/Inputs/root-relative-overlay.yaml
@@ -0,0 +1,11 @@
+{
+  'version': 0,
+  'case-sensitive': false,
+  'overlay-relative': OVERLAY_DIR,
+  'root-relative': 'overlay-dir',
+  'roots': [
+    { 'name': 'not_real.h', 'type': 'file',
+      'external-contents': 'EXTERNAL_DIR/actual_header.h'
+    },
+  ]
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to