Skip to content

Commit

Permalink
[clang] Implement PointerLikeTraits for {File,Directory}EntryRef
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jansvoboda11 committed Jul 11, 2023
1 parent bdbb3fd commit 06611e3
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 15 deletions.
17 changes: 16 additions & 1 deletion clang/include/clang/Basic/DirectoryEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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() {
Expand Down
15 changes: 15 additions & 0 deletions clang/include/clang/Basic/FileEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
13 changes: 5 additions & 8 deletions clang/include/clang/Basic/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Basic/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Lex/ModuleMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down

0 comments on commit 06611e3

Please sign in to comment.