This revision was automatically updated to reflect the committed changes.
Closed by commit rG3c7f6b439699: [clang][modules] Add support for merging
lifetime-extended temporaries (authored by Tyker).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D70190/new/
https://reviews.llvm.org/D70190
Files:
clang/include/clang/AST/DeclCXX.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Serialization/ASTReader.h
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
clang/test/Modules/merge-lifetime-extended-temporary.cpp
Index: clang/test/Modules/merge-lifetime-extended-temporary.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/merge-lifetime-extended-temporary.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=1
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=2
+
+// expected-no-diagnostics
+#if ORDER == 1
+#include "c.h"
+#include "b.h"
+#else
+#include "b.h"
+#include "c.h"
+#endif
+
+static_assert(PtrTemp1 == &LETemp, "");
+static_assert(PtrTemp1 == PtrTemp2, "");
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
@@ -0,0 +1,14 @@
+module "a" {
+ export *
+ header "a.h"
+}
+
+module "b" {
+ export *
+ header "b.h"
+}
+
+module "c" {
+ export *
+ header "c.h"
+}
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp2 = &LETemp;
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp1 = &LETemp;
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
@@ -0,0 +1,2 @@
+
+constexpr const int& LETemp = 0;
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -424,6 +424,9 @@
template<typename T>
void mergeMergeable(Mergeable<T> *D);
+ template <>
+ void mergeMergeable(Mergeable<LifetimeExtendedTemporaryDecl> *D);
+
void mergeTemplatePattern(RedeclarableTemplateDecl *D,
RedeclarableTemplateDecl *Existing,
DeclID DsID, bool IsKeyDecl);
@@ -2358,6 +2361,7 @@
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 +2559,28 @@
return false;
}
+/// Attempts to merge LifetimeExtendedTemporaryDecl with
+/// identical class definitions from two different modules.
+template<>
+void ASTDeclReader::mergeMergeable(
+ Mergeable<LifetimeExtendedTemporaryDecl> *D) {
+ // If modules are not available, there is no reason to perform this merge.
+ if (!Reader.getContext().getLangOpts().Modules)
+ return;
+
+ LifetimeExtendedTemporaryDecl *LETDecl =
+ static_cast<LifetimeExtendedTemporaryDecl *>(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
Index: clang/lib/AST/TextNodeDumper.cpp
===================================================================
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1338,6 +1338,17 @@
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());
Index: clang/include/clang/Serialization/ASTReader.h
===================================================================
--- clang/include/clang/Serialization/ASTReader.h
+++ clang/include/clang/Serialization/ASTReader.h
@@ -551,6 +551,14 @@
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;
Index: clang/include/clang/AST/TextNodeDumper.h
===================================================================
--- clang/include/clang/AST/TextNodeDumper.h
+++ clang/include/clang/AST/TextNodeDumper.h
@@ -346,6 +346,8 @@
void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
void VisitBlockDecl(const BlockDecl *D);
void VisitConceptDecl(const ConceptDecl *D);
+ void
+ VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
};
} // namespace clang
Index: clang/include/clang/AST/DeclCXX.h
===================================================================
--- clang/include/clang/AST/DeclCXX.h
+++ clang/include/clang/AST/DeclCXX.h
@@ -3041,7 +3041,9 @@
/// 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;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits