This revision was automatically updated to reflect the committed changes.
Closed by commit rG32c501dd88b6: Module: Use FileEntryRef and DirectoryEntryRef
in Umbrella, Header, and… (authored by dexonsmith).
Herald added a project: clang.
Changed prior to commit:
https://reviews.llvm.org/D90497?vs=302022&id=309054#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D90497/new/
https://reviews.llvm.org/D90497
Files:
clang/include/clang/Basic/DirectoryEntry.h
clang/include/clang/Basic/Module.h
clang/include/clang/Lex/ModuleMap.h
clang/lib/Basic/Module.cpp
clang/lib/Frontend/FrontendActions.cpp
clang/lib/Lex/ModuleMap.cpp
clang/lib/Serialization/ASTReader.cpp
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1915,7 +1915,8 @@
// FIXME: This is not always the right filename-as-written, but we're not
// going to use this information to rebuild the module, so it doesn't make
// a lot of difference.
- Module::Header H = {std::string(key.Filename), *FileMgr.getFile(Filename)};
+ Module::Header H = {std::string(key.Filename),
+ *FileMgr.getOptionalFileRef(Filename)};
ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true);
HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader);
}
@@ -5564,7 +5565,7 @@
case SUBMODULE_UMBRELLA_HEADER: {
std::string Filename = std::string(Blob);
ResolveImportedPath(F, Filename);
- if (auto Umbrella = PP.getFileManager().getFile(Filename)) {
+ if (auto Umbrella = PP.getFileManager().getOptionalFileRef(Filename)) {
if (!CurrentModule->getUmbrellaHeader())
ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob);
else if (CurrentModule->getUmbrellaHeader().Entry != *Umbrella) {
@@ -5597,7 +5598,8 @@
case SUBMODULE_UMBRELLA_DIR: {
std::string Dirname = std::string(Blob);
ResolveImportedPath(F, Dirname);
- if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) {
+ if (auto Umbrella =
+ PP.getFileManager().getOptionalDirectoryRef(Dirname)) {
if (!CurrentModule->getUmbrellaDir())
ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob);
else if (CurrentModule->getUmbrellaDir().Entry != *Umbrella) {
Index: clang/lib/Lex/ModuleMap.cpp
===================================================================
--- clang/lib/Lex/ModuleMap.cpp
+++ clang/lib/Lex/ModuleMap.cpp
@@ -300,7 +300,7 @@
// supplied by Clang. Find that builtin header.
SmallString<128> Path;
llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
- auto File = SourceMgr.getFileManager().getFile(Path);
+ auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);
if (!File)
return false;
@@ -1012,7 +1012,7 @@
// Look for an umbrella header.
SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
- auto UmbrellaHeader = FileMgr.getFile(UmbrellaName);
+ auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);
// FIXME: If there's no umbrella header, we could probably scan the
// framework to load *everything*. But, it's not clear that this is a good
@@ -1121,21 +1121,21 @@
return Result;
}
-void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
+void ModuleMap::setUmbrellaHeader(Module *Mod, FileEntryRef UmbrellaHeader,
Twine NameAsWritten) {
Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
- Mod->Umbrella = UmbrellaHeader;
+ Mod->Umbrella = &UmbrellaHeader.getMapEntry();
Mod->UmbrellaAsWritten = NameAsWritten.str();
- UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
+ UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
// Notify callbacks that we just added a new header.
for (const auto &Cb : Callbacks)
Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
}
-void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
+void ModuleMap::setUmbrellaDir(Module *Mod, DirectoryEntryRef UmbrellaDir,
Twine NameAsWritten) {
- Mod->Umbrella = UmbrellaDir;
+ Mod->Umbrella = &UmbrellaDir.getMapEntry();
Mod->UmbrellaAsWritten = NameAsWritten.str();
UmbrellaDirs[UmbrellaDir] = Mod;
}
@@ -2416,15 +2416,15 @@
}
// Look for this file.
- const DirectoryEntry *Dir = nullptr;
+ Optional<DirectoryEntryRef> Dir;
if (llvm::sys::path::is_absolute(DirName)) {
- if (auto D = SourceMgr.getFileManager().getDirectory(DirName))
+ if (auto D = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName))
Dir = *D;
} else {
SmallString<128> PathName;
PathName = Directory->getName();
llvm::sys::path::append(PathName, DirName);
- if (auto D = SourceMgr.getFileManager().getDirectory(PathName))
+ if (auto D = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName))
Dir = *D;
}
@@ -2445,7 +2445,7 @@
SourceMgr.getFileManager().getVirtualFileSystem();
for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
I != E && !EC; I.increment(EC)) {
- if (auto FE = SourceMgr.getFileManager().getFile(I->path())) {
+ if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
Module::Header Header = {std::string(I->path()), *FE};
Headers.push_back(std::move(Header));
}
@@ -2459,7 +2459,7 @@
return;
}
- if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
+ if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
<< OwningModule->getFullModuleName();
HadError = true;
@@ -2467,7 +2467,7 @@
}
// Record this umbrella directory.
- Map.setUmbrellaDir(ActiveModule, Dir, DirName);
+ Map.setUmbrellaDir(ActiveModule, *Dir, DirName);
}
/// Parse a module export declaration.
Index: clang/lib/Frontend/FrontendActions.cpp
===================================================================
--- clang/lib/Frontend/FrontendActions.cpp
+++ clang/lib/Frontend/FrontendActions.cpp
@@ -304,7 +304,7 @@
<< Name;
continue;
}
- Headers.push_back({std::string(Name), &FE->getFileEntry()});
+ Headers.push_back({std::string(Name), *FE});
}
HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers);
Index: clang/lib/Basic/Module.cpp
===================================================================
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -247,7 +247,10 @@
if (Header U = getUmbrellaHeader())
return {"", U.Entry->getDir()};
- return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
+ if (auto *ME = Umbrella.dyn_cast<const DirectoryEntryRef::MapEntry *>())
+ return {UmbrellaAsWritten, DirectoryEntryRef(*ME)};
+
+ return {"", None};
}
void Module::addTopHeader(const FileEntry *File) {
Index: clang/include/clang/Lex/ModuleMap.h
===================================================================
--- clang/include/clang/Lex/ModuleMap.h
+++ clang/include/clang/Lex/ModuleMap.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_LEX_MODULEMAP_H
#define LLVM_CLANG_LEX_MODULEMAP_H
+#include "clang/Basic/FileEntry.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
@@ -37,7 +38,6 @@
class DiagnosticsEngine;
class DirectoryEntry;
-class FileEntry;
class FileManager;
class HeaderSearch;
class SourceManager;
@@ -648,12 +648,12 @@
/// Sets the umbrella header of the given module to the given
/// header.
- void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
+ void setUmbrellaHeader(Module *Mod, FileEntryRef UmbrellaHeader,
Twine NameAsWritten);
/// Sets the umbrella directory of the given module to the given
/// directory.
- void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
+ void setUmbrellaDir(Module *Mod, DirectoryEntryRef UmbrellaDir,
Twine NameAsWritten);
/// Adds this header to the given module.
Index: clang/include/clang/Basic/Module.h
===================================================================
--- clang/include/clang/Basic/Module.h
+++ clang/include/clang/Basic/Module.h
@@ -133,7 +133,9 @@
std::string PresumedModuleMapFile;
/// The umbrella header or directory.
- llvm::PointerUnion<const FileEntry *, const DirectoryEntry *> Umbrella;
+ llvm::PointerUnion<const FileEntryRef::MapEntry *,
+ const DirectoryEntryRef::MapEntry *>
+ Umbrella;
/// The module signature.
ASTFileSignature Signature;
@@ -188,18 +190,18 @@
/// file.
struct Header {
std::string NameAsWritten;
- const FileEntry *Entry;
+ OptionalFileEntryRefDegradesToFileEntryPtr Entry;
- explicit operator bool() { return Entry; }
+ explicit operator bool() { return Entry != None; }
};
/// Information about a directory name as found in the module map
/// file.
struct DirectoryName {
std::string NameAsWritten;
- const DirectoryEntry *Entry;
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr Entry;
- explicit operator bool() { return Entry; }
+ explicit operator bool() { return Entry != None; }
};
/// The headers that are part of this module.
@@ -544,15 +546,15 @@
/// Retrieve the header that serves as the umbrella header for this
/// module.
Header getUmbrellaHeader() const {
- if (auto *FE = Umbrella.dyn_cast<const FileEntry *>())
- return Header{UmbrellaAsWritten, FE};
+ if (auto *ME = Umbrella.dyn_cast<const FileEntryRef::MapEntry *>())
+ return Header{UmbrellaAsWritten, FileEntryRef(*ME)};
return Header{};
}
/// Determine whether this module has an umbrella directory that is
/// not based on an umbrella header.
bool hasUmbrellaDir() const {
- return Umbrella && Umbrella.is<const DirectoryEntry *>();
+ return Umbrella && Umbrella.is<const DirectoryEntryRef::MapEntry *>();
}
/// Add a top-level header associated with this module.
Index: clang/include/clang/Basic/DirectoryEntry.h
===================================================================
--- clang/include/clang/Basic/DirectoryEntry.h
+++ clang/include/clang/Basic/DirectoryEntry.h
@@ -51,7 +51,26 @@
const MapEntry &getMapEntry() const { return *ME; }
DirectoryEntryRef() = delete;
- DirectoryEntryRef(MapEntry &ME) : ME(&ME) {}
+ DirectoryEntryRef(const MapEntry &ME) : ME(&ME) {}
+
+ /// Allow DirectoryEntryRef to degrade into 'const DirectoryEntry*' to
+ /// facilitate incremental adoption.
+ ///
+ /// The goal is to avoid code churn due to dances like the following:
+ /// \code
+ /// // Old code.
+ /// lvalue = rvalue;
+ ///
+ /// // Temporary code from an incremental patch.
+ /// lvalue = &rvalue.getDirectoryEntry();
+ ///
+ /// // Final code.
+ /// lvalue = rvalue;
+ /// \endcode
+ ///
+ /// FIXME: Once DirectoryEntryRef is "everywhere" and DirectoryEntry::getName
+ /// has been deleted, delete this implicit conversion.
+ operator const DirectoryEntry *() const { return &getDirEntry(); }
private:
friend class FileMgr::MapEntryOptionalStorage<DirectoryEntryRef>;
@@ -147,4 +166,76 @@
} // end namespace optional_detail
} // end namespace llvm
+namespace clang {
+
+/// Wrapper around Optional<DirectoryEntryRef> that degrades to 'const
+/// DirectoryEntry*', facilitating incremental patches to propagate
+/// DirectoryEntryRef.
+///
+/// This class can be used as return value or field where it's convenient for
+/// an Optional<DirectoryEntryRef> to degrade to a 'const DirectoryEntry*'. The
+/// purpose is to avoid code churn due to dances like the following:
+/// \code
+/// // Old code.
+/// lvalue = rvalue;
+///
+/// // Temporary code from an incremental patch.
+/// Optional<DirectoryEntryRef> MaybeF = rvalue;
+/// lvalue = MaybeF ? &MaybeF.getDirectoryEntry() : nullptr;
+///
+/// // Final code.
+/// lvalue = rvalue;
+/// \endcode
+///
+/// FIXME: Once DirectoryEntryRef is "everywhere" and DirectoryEntry::LastRef
+/// and DirectoryEntry::getName have been deleted, delete this class and
+/// replace instances with Optional<DirectoryEntryRef>.
+class OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr
+ : public Optional<DirectoryEntryRef> {
+public:
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr() = default;
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &&) = default;
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(
+ const OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &) = default;
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
+ operator=(OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &&) = default;
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
+ operator=(const OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &) = default;
+
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(llvm::NoneType) {}
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(DirectoryEntryRef Ref)
+ : Optional<DirectoryEntryRef>(Ref) {}
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(Optional<DirectoryEntryRef> MaybeRef)
+ : Optional<DirectoryEntryRef>(MaybeRef) {}
+
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &operator=(llvm::NoneType) {
+ Optional<DirectoryEntryRef>::operator=(None);
+ return *this;
+ }
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &operator=(DirectoryEntryRef Ref) {
+ Optional<DirectoryEntryRef>::operator=(Ref);
+ return *this;
+ }
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
+ operator=(Optional<DirectoryEntryRef> MaybeRef) {
+ Optional<DirectoryEntryRef>::operator=(MaybeRef);
+ return *this;
+ }
+
+ /// Degrade to 'const DirectoryEntry *' to allow DirectoryEntry::LastRef and
+ /// DirectoryEntry::getName have been deleted, delete this class and replace
+ /// instances with Optional<DirectoryEntryRef>
+ operator const DirectoryEntry *() const {
+ return hasValue() ? &getValue().getDirEntry() : nullptr;
+ }
+};
+
+static_assert(std::is_trivially_copyable<
+ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr>::value,
+ "OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr should be "
+ "trivially copyable");
+
+} // end namespace clang
+
#endif // LLVM_CLANG_BASIC_DIRECTORYENTRY_H
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits