From 2751b69dd3945ef9bd1298c16dca5b59076f8f17 Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Thu, 18 Apr 2019 15:13:27 +0000 Subject: [Serialization] Stable serialization order for OpenCLTypeExtMap and OpenCLDeclExtMap Sort the elements of Sema::OpenCLTypeExtMap and Sema::OpenCLDeclExtMap by TypeIDs and DeclIDs to guarantee a stable serialization order. Differential Revision: https://reviews.llvm.org/D60835 Reviewed By: Anastasia Reviewers: Anastasia, lebedev.ri llvm-svn: 358674 --- clang/lib/Serialization/ASTWriter.cpp | 54 +++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'clang/lib/Serialization/ASTWriter.cpp') diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 3609e589193..756411a8c5b 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -4278,14 +4278,32 @@ void ASTWriter::WriteOpenCLExtensionTypes(Sema &SemaRef) { if (!SemaRef.Context.getLangOpts().OpenCL) return; + // Sort the elements of the map OpenCLTypeExtMap by TypeIDs, + // without copying them. + const llvm::DenseMap> &OpenCLTypeExtMap = + SemaRef.OpenCLTypeExtMap; + using ElementTy = std::pair *>; + llvm::SmallVector StableOpenCLTypeExtMap; + StableOpenCLTypeExtMap.reserve(OpenCLTypeExtMap.size()); + + for (const auto &I : OpenCLTypeExtMap) + StableOpenCLTypeExtMap.emplace_back( + getTypeID(I.first->getCanonicalTypeInternal()), &I.second); + + auto CompareByTypeID = [](const ElementTy &E1, const ElementTy &E2) -> bool { + return E1.first < E2.first; + }; + llvm::sort(StableOpenCLTypeExtMap, CompareByTypeID); + RecordData Record; - for (const auto &I : SemaRef.OpenCLTypeExtMap) { - Record.push_back( - static_cast(getTypeID(I.first->getCanonicalTypeInternal()))); - Record.push_back(I.second.size()); - for (auto Ext : I.second) + for (const ElementTy &E : StableOpenCLTypeExtMap) { + Record.push_back(E.first); // TypeID + const std::set *ExtSet = E.second; + Record.push_back(static_cast(ExtSet->size())); + for (const std::string &Ext : *ExtSet) AddString(Ext, Record); } + Stream.EmitRecord(OPENCL_EXTENSION_TYPES, Record); } @@ -4293,13 +4311,31 @@ void ASTWriter::WriteOpenCLExtensionDecls(Sema &SemaRef) { if (!SemaRef.Context.getLangOpts().OpenCL) return; + // Sort the elements of the map OpenCLDeclExtMap by DeclIDs, + // without copying them. + const llvm::DenseMap> &OpenCLDeclExtMap = + SemaRef.OpenCLDeclExtMap; + using ElementTy = std::pair *>; + llvm::SmallVector StableOpenCLDeclExtMap; + StableOpenCLDeclExtMap.reserve(OpenCLDeclExtMap.size()); + + for (const auto &I : OpenCLDeclExtMap) + StableOpenCLDeclExtMap.emplace_back(getDeclID(I.first), &I.second); + + auto CompareByDeclID = [](const ElementTy &E1, const ElementTy &E2) -> bool { + return E1.first < E2.first; + }; + llvm::sort(StableOpenCLDeclExtMap, CompareByDeclID); + RecordData Record; - for (const auto &I : SemaRef.OpenCLDeclExtMap) { - Record.push_back(getDeclID(I.first)); - Record.push_back(static_cast(I.second.size())); - for (auto Ext : I.second) + for (const ElementTy &E : StableOpenCLDeclExtMap) { + Record.push_back(E.first); // DeclID + const std::set *ExtSet = E.second; + Record.push_back(static_cast(ExtSet->size())); + for (const std::string &Ext : *ExtSet) AddString(Ext, Record); } + Stream.EmitRecord(OPENCL_EXTENSION_DECLS, Record); } -- cgit v1.2.3