Unverified Commit 1afb313b authored by Jan Svoboda's avatar Jan Svoboda Committed by GitHub
Browse files

[clang][modules] Use file name as requested (#68957)

This prevents redefinition errors due to having multiple paths for the
same module map. (rdar://24116019)

Originally implemented and tested downstream by @bcardosolopes, I just
made use of `FileEntryRef::getNameAsRequested()`.
parent cb62f670
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -12,10 +12,10 @@
#include "clang/Basic/FileEntry.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
#include <variant>

namespace llvm {
  class MemoryBuffer;
@@ -33,7 +33,7 @@ class FileRemapper {
  // FIXME: Reuse the same FileManager for multiple ASTContexts.
  std::unique_ptr<FileManager> FileMgr;

  typedef llvm::PointerUnion<FileEntryRef, llvm::MemoryBuffer *> Target;
  using Target = std::variant<FileEntryRef, llvm::MemoryBuffer *>;
  using MappingsTy = llvm::DenseMap<FileEntryRef, Target>;
  MappingsTy FromToMappings;

+0 −31
Original line number Diff line number Diff line
@@ -235,37 +235,6 @@ static_assert(std::is_trivially_copyable<OptionalFileEntryRef>::value,

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;
};

template <> struct PointerLikeTypeTraits<clang::OptionalFileEntryRef> {
  static inline void *getAsVoidPointer(clang::OptionalFileEntryRef File) {
    if (!File)
      return nullptr;
    return PointerLikeTypeTraits<clang::FileEntryRef>::getAsVoidPointer(*File);
  }

  static inline clang::OptionalFileEntryRef getFromVoidPointer(void *Ptr) {
    if (!Ptr)
      return std::nullopt;
    return PointerLikeTypeTraits<clang::FileEntryRef>::getFromVoidPointer(Ptr);
  }

  static constexpr int NumLowBitsAvailable =
      PointerLikeTypeTraits<clang::FileEntryRef>::NumLowBitsAvailable;
};

/// Specialisation of DenseMapInfo for FileEntryRef.
template <> struct DenseMapInfo<clang::FileEntryRef> {
  static inline clang::FileEntryRef getEmptyKey() {
+6 −6
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <optional>
#include <string>
#include <utility>
#include <variant>
#include <vector>

namespace llvm {
@@ -162,7 +163,7 @@ public:
  std::string PresumedModuleMapFile;

  /// The umbrella header or directory.
  llvm::PointerUnion<FileEntryRef, DirectoryEntryRef> Umbrella;
  std::variant<std::monostate, FileEntryRef, DirectoryEntryRef> Umbrella;

  /// The module signature.
  ASTFileSignature Signature;
@@ -665,18 +666,17 @@ public:

  /// Retrieve the umbrella directory as written.
  std::optional<DirectoryName> getUmbrellaDirAsWritten() const {
    if (Umbrella && Umbrella.is<DirectoryEntryRef>())
    if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
      return DirectoryName{UmbrellaAsWritten,
                           UmbrellaRelativeToRootModuleDirectory,
                           Umbrella.get<DirectoryEntryRef>()};
                           UmbrellaRelativeToRootModuleDirectory, *Dir};
    return std::nullopt;
  }

  /// Retrieve the umbrella header as written.
  std::optional<Header> getUmbrellaHeaderAsWritten() const {
    if (Umbrella && Umbrella.is<FileEntryRef>())
    if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
      return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
                    Umbrella.get<FileEntryRef>()};
                    *Hdr};
    return std::nullopt;
  }

+5 −4
Original line number Diff line number Diff line
@@ -278,14 +278,15 @@ private:

  // These facilities are used for validation in debug builds.
  class UnparsedFileStatus {
    llvm::PointerIntPair<OptionalFileEntryRef, 1, bool> Data;
    OptionalFileEntryRef File;
    bool FoundDirectives;

  public:
    UnparsedFileStatus(OptionalFileEntryRef File, bool FoundDirectives)
        : Data(File, FoundDirectives) {}
        : File(File), FoundDirectives(FoundDirectives) {}

    OptionalFileEntryRef getFile() const { return Data.getPointer(); }
    bool foundDirectives() const { return Data.getInt(); }
    OptionalFileEntryRef getFile() const { return File; }
    bool foundDirectives() const { return FoundDirectives; }
  };

  using ParsedFilesMap = llvm::DenseMap<FileID, const FileEntry *>;
+2 −2
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -194,7 +194,7 @@ public:
    }
  };

  using AdditionalModMapsSet = llvm::SmallPtrSet<FileEntryRef, 1>;
  using AdditionalModMapsSet = llvm::DenseSet<FileEntryRef>;

private:
  friend class ModuleMapParser;
Loading