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(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits