Commit 85c74384 authored by Tyker's avatar Tyker
Browse files

[clang][modules] Add support for merging lifetime-extended temporaries

Summary: Add support for merging lifetime-extended temporaries

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: xbolva00, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D70190
parent 8682d29a
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -3041,7 +3041,9 @@ public:

/// Implicit declaration of a temporary that was materialized by
/// a MaterializeTemporaryExpr and lifetime-extended by a declaration
class LifetimeExtendedTemporaryDecl final : public Decl {
class LifetimeExtendedTemporaryDecl final
    : public Decl,
      public Mergeable<LifetimeExtendedTemporaryDecl> {
  friend class MaterializeTemporaryExpr;
  friend class ASTDeclReader;

+2 −0
Original line number Diff line number Diff line
@@ -346,6 +346,8 @@ public:
  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
  void VisitBlockDecl(const BlockDecl *D);
  void VisitConceptDecl(const ConceptDecl *D);
  void
  VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
};

} // namespace clang
+8 −0
Original line number Diff line number Diff line
@@ -551,6 +551,14 @@ private:
  llvm::DenseMap<Decl*, llvm::SmallVector<NamedDecl*, 2>>
    AnonymousDeclarationsForMerging;

  /// Key used to identify LifetimeExtendedTemporaryDecl for merging,
  /// containing the lifetime-extending declaration and the mangling number.
  using LETemporaryKey = std::pair<Decl *, unsigned>;

  /// Map of already deserialiazed temporaries.
  llvm::DenseMap<LETemporaryKey, LifetimeExtendedTemporaryDecl *>
      LETemporaryForMerging;

  struct FileDeclsInfo {
    ModuleFile *Mod = nullptr;
    ArrayRef<serialization::LocalDeclID> Decls;
+11 −0
Original line number Diff line number Diff line
@@ -1338,6 +1338,17 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
    OS << " <<<NULL params x " << D->getNumParams() << ">>>";
}

void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
    const LifetimeExtendedTemporaryDecl *D) {
  OS << " extended by ";
  dumpBareDeclRef(D->getExtendingDecl());
  OS << " mangling ";
  {
    ColorScope Color(OS, ShowColors, ValueColor);
    OS << D->getManglingNumber();
  }
}

void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
  dumpName(D);
  dumpType(D->getType());
+22 −0
Original line number Diff line number Diff line
@@ -424,6 +424,8 @@ namespace clang {
    template<typename T>
    void mergeMergeable(Mergeable<T> *D);

    void mergeMergeable(LifetimeExtendedTemporaryDecl *D);

    void mergeTemplatePattern(RedeclarableTemplateDecl *D,
                              RedeclarableTemplateDecl *Existing,
                              DeclID DsID, bool IsKeyDecl);
@@ -2358,6 +2360,7 @@ void ASTDeclReader::VisitLifetimeExtendedTemporaryDecl(
  if (Record.readInt())
    D->Value = new (D->getASTContext()) APValue(Record.readAPValue());
  D->ManglingNumber = Record.readInt();
  mergeMergeable(D);
}

std::pair<uint64_t, uint64_t>
@@ -2555,6 +2558,25 @@ static bool allowODRLikeMergeInC(NamedDecl *ND) {
  return false;
}

/// Attempts to merge LifetimeExtendedTemporaryDecl with
/// identical class definitions from two different modules.
void ASTDeclReader::mergeMergeable(LifetimeExtendedTemporaryDecl *D) {
  // If modules are not available, there is no reason to perform this merge.
  if (!Reader.getContext().getLangOpts().Modules)
    return;

  LifetimeExtendedTemporaryDecl *LETDecl = D;

  LifetimeExtendedTemporaryDecl *&LookupResult =
      Reader.LETemporaryForMerging[std::make_pair(
          LETDecl->getExtendingDecl(), LETDecl->getManglingNumber())];
  if (LookupResult)
    Reader.getContext().setPrimaryMergedDecl(LETDecl,
                                             LookupResult->getCanonicalDecl());
  else
    LookupResult = LETDecl;
}

/// Attempts to merge the given declaration (D) with another declaration
/// of the same entity, for the case where the entity is not actually
/// redeclarable. This happens, for instance, when merging the fields of
Loading