Author: Tyker Date: 2019-12-01T21:28:48+01:00 New Revision: a3cbe1a202df6ec8e23bd55e14db254e4bc33021
URL: https://github.com/llvm/llvm-project/commit/a3cbe1a202df6ec8e23bd55e14db254e4bc33021 DIFF: https://github.com/llvm/llvm-project/commit/a3cbe1a202df6ec8e23bd55e14db254e4bc33021.diff LOG: [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 Added: 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 Modified: 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 Removed: ################################################################################ diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 63d67bd3f55b..0f2018fb9e8c 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -3041,7 +3041,9 @@ class NamespaceAliasDecl : public NamedDecl, /// 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; diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 0ff5a614a864..d293ea190aa4 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -346,6 +346,8 @@ class TextNodeDumper void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); void VisitBlockDecl(const BlockDecl *D); void VisitConceptDecl(const ConceptDecl *D); + void + VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D); }; } // namespace clang diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index f0b5e9933823..b6dae68b3413 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -551,6 +551,14 @@ class ASTReader 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; diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 0ff95213118f..561c76a45cbc 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -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()); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 8991a39a7067..3f7a1ed7fd5c 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -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 diff erent 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 diff --git a/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h b/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h new file mode 100644 index 000000000000..8adab29eafc7 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h @@ -0,0 +1,2 @@ + +constexpr const int& LETemp = 0; diff --git a/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h b/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h new file mode 100644 index 000000000000..2bd1b096d607 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h @@ -0,0 +1,4 @@ + +#include "a.h" + +constexpr const int* PtrTemp1 = &LETemp; diff --git a/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h b/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h new file mode 100644 index 000000000000..b023eebca49c --- /dev/null +++ b/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h @@ -0,0 +1,4 @@ + +#include "a.h" + +constexpr const int* PtrTemp2 = &LETemp; diff --git a/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap b/clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap new file mode 100644 index 000000000000..1339d627a44a --- /dev/null +++ b/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" +} diff --git a/clang/test/Modules/merge-lifetime-extended-temporary.cpp b/clang/test/Modules/merge-lifetime-extended-temporary.cpp new file mode 100644 index 000000000000..36db948b2c4e --- /dev/null +++ b/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, ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits