[clang] 06611e3 - [clang] Implement `PointerLikeTraits` for `{File,Directory}EntryRef`

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 11 11:17:50 PDT 2023


Author: Jan Svoboda
Date: 2023-07-11T11:17:24-07:00
New Revision: 06611e361363a4c209aaccd0ee24652d2c56cafb

URL: https://github.com/llvm/llvm-project/commit/06611e361363a4c209aaccd0ee24652d2c56cafb
DIFF: https://github.com/llvm/llvm-project/commit/06611e361363a4c209aaccd0ee24652d2c56cafb.diff

LOG: [clang] Implement `PointerLikeTraits` for `{File,Directory}EntryRef`

This patch implements `llvm::PointerLikeTraits<FileEntryRef>` and `llvm::PointerLikeTraits<DirectoryEntryRef>`, allowing some simplifications around umbrella header/directory code.

Reviewed By: benlangmuir

Differential Revision: https://reviews.llvm.org/D154905

Added: 
    

Modified: 
    clang/include/clang/Basic/DirectoryEntry.h
    clang/include/clang/Basic/FileEntry.h
    clang/include/clang/Basic/Module.h
    clang/lib/Basic/Module.cpp
    clang/lib/Lex/ModuleMap.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DirectoryEntry.h b/clang/include/clang/Basic/DirectoryEntry.h
index 6580e54e3c58b8..5d083e68facd7a 100644
--- a/clang/include/clang/Basic/DirectoryEntry.h
+++ b/clang/include/clang/Basic/DirectoryEntry.h
@@ -72,7 +72,7 @@ class DirectoryEntryRef {
   bool isSameRef(DirectoryEntryRef RHS) const { return ME == RHS.ME; }
 
   DirectoryEntryRef() = delete;
-  DirectoryEntryRef(const MapEntry &ME) : ME(&ME) {}
+  explicit DirectoryEntryRef(const MapEntry &ME) : ME(&ME) {}
 
   /// Allow DirectoryEntryRef to degrade into 'const DirectoryEntry*' to
   /// facilitate incremental adoption.
@@ -197,6 +197,21 @@ static_assert(std::is_trivially_copyable<OptionalDirectoryEntryRef>::value,
 } // namespace clang
 
 namespace llvm {
+
+template <> struct PointerLikeTypeTraits<clang::DirectoryEntryRef> {
+  static inline void *getAsVoidPointer(clang::DirectoryEntryRef Dir) {
+    return const_cast<clang::DirectoryEntryRef::MapEntry *>(&Dir.getMapEntry());
+  }
+
+  static inline clang::DirectoryEntryRef getFromVoidPointer(void *Ptr) {
+    return clang::DirectoryEntryRef(
+        *reinterpret_cast<const clang::DirectoryEntryRef::MapEntry *>(Ptr));
+  }
+
+  static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<
+      const clang::DirectoryEntryRef::MapEntry *>::NumLowBitsAvailable;
+};
+
 /// Specialisation of DenseMapInfo for DirectoryEntryRef.
 template <> struct DenseMapInfo<clang::DirectoryEntryRef> {
   static inline clang::DirectoryEntryRef getEmptyKey() {

diff  --git a/clang/include/clang/Basic/FileEntry.h b/clang/include/clang/Basic/FileEntry.h
index fdeafe5348cd08..50110b8572ef48 100644
--- a/clang/include/clang/Basic/FileEntry.h
+++ b/clang/include/clang/Basic/FileEntry.h
@@ -234,6 +234,21 @@ static_assert(std::is_trivially_copyable<OptionalFileEntryRef>::value,
 } // namespace clang
 
 namespace llvm {
+
+template <> struct PointerLikeTypeTraits<clang::FileEntryRef> {
+  static inline void *getAsVoidPointer(clang::FileEntryRef File) {
+    return const_cast<clang::FileEntryRef::MapEntry *>(&File.getMapEntry());
+  }
+
+  static inline clang::FileEntryRef getFromVoidPointer(void *Ptr) {
+    return clang::FileEntryRef(
+        *reinterpret_cast<const clang::FileEntryRef::MapEntry *>(Ptr));
+  }
+
+  static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<
+      const clang::FileEntryRef::MapEntry *>::NumLowBitsAvailable;
+};
+
 /// Specialisation of DenseMapInfo for FileEntryRef.
 template <> struct DenseMapInfo<clang::FileEntryRef> {
   static inline clang::FileEntryRef getEmptyKey() {

diff  --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h
index b3b53761601071..a4ad8ad2f768fe 100644
--- a/clang/include/clang/Basic/Module.h
+++ b/clang/include/clang/Basic/Module.h
@@ -156,9 +156,7 @@ class alignas(8) Module {
   std::string PresumedModuleMapFile;
 
   /// The umbrella header or directory.
-  llvm::PointerUnion<const FileEntryRef::MapEntry *,
-                     const DirectoryEntryRef::MapEntry *>
-      Umbrella;
+  llvm::PointerUnion<FileEntryRef, DirectoryEntryRef> Umbrella;
 
   /// The module signature.
   ASTFileSignature Signature;
@@ -650,19 +648,18 @@ class alignas(8) Module {
 
   /// Retrieve the umbrella directory as written.
   std::optional<DirectoryName> getUmbrellaDirAsWritten() const {
-    if (const auto *ME =
-            Umbrella.dyn_cast<const DirectoryEntryRef::MapEntry *>())
+    if (Umbrella && Umbrella.is<DirectoryEntryRef>())
       return DirectoryName{UmbrellaAsWritten,
                            UmbrellaRelativeToRootModuleDirectory,
-                           DirectoryEntryRef(*ME)};
+                           Umbrella.get<DirectoryEntryRef>()};
     return std::nullopt;
   }
 
   /// Retrieve the umbrella header as written.
   std::optional<Header> getUmbrellaHeaderAsWritten() const {
-    if (const auto *ME = Umbrella.dyn_cast<const FileEntryRef::MapEntry *>())
+    if (Umbrella && Umbrella.is<FileEntryRef>())
       return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
-                    FileEntryRef(*ME)};
+                    Umbrella.get<FileEntryRef>()};
     return std::nullopt;
   }
 

diff  --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp
index 2bdbe8d2b110d7..8ec68237a0fc08 100644
--- a/clang/lib/Basic/Module.cpp
+++ b/clang/lib/Basic/Module.cpp
@@ -264,10 +264,10 @@ bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
 }
 
 OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
-  if (const auto *ME = Umbrella.dyn_cast<const FileEntryRef::MapEntry *>())
-    return FileEntryRef(*ME).getDir();
-  if (const auto *ME = Umbrella.dyn_cast<const DirectoryEntryRef::MapEntry *>())
-    return DirectoryEntryRef(*ME);
+  if (Umbrella && Umbrella.is<FileEntryRef>())
+    return Umbrella.get<FileEntryRef>().getDir();
+  if (Umbrella && Umbrella.is<DirectoryEntryRef>())
+    return Umbrella.get<DirectoryEntryRef>();
   return std::nullopt;
 }
 

diff  --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 7a22fead3a0896..c480719abc3679 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -1162,7 +1162,7 @@ void ModuleMap::setUmbrellaHeaderAsWritten(
     Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
     const Twine &PathRelativeToRootModuleDirectory) {
   Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
-  Mod->Umbrella = &UmbrellaHeader.getMapEntry();
+  Mod->Umbrella = UmbrellaHeader;
   Mod->UmbrellaAsWritten = NameAsWritten.str();
   Mod->UmbrellaRelativeToRootModuleDirectory =
       PathRelativeToRootModuleDirectory.str();
@@ -1176,7 +1176,7 @@ void ModuleMap::setUmbrellaHeaderAsWritten(
 void ModuleMap::setUmbrellaDirAsWritten(
     Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,
     const Twine &PathRelativeToRootModuleDirectory) {
-  Mod->Umbrella = &UmbrellaDir.getMapEntry();
+  Mod->Umbrella = UmbrellaDir;
   Mod->UmbrellaAsWritten = NameAsWritten.str();
   Mod->UmbrellaRelativeToRootModuleDirectory =
       PathRelativeToRootModuleDirectory.str();


        


More information about the cfe-commits mailing list