Index: lib/Serialization/ASTCommon.h =================================================================== --- lib/Serialization/ASTCommon.h +++ lib/Serialization/ASTCommon.h @@ -96,6 +96,7 @@ template void numberAnonymousDeclsWithin(const DeclContext *DC, Fn Visit) { unsigned Index = 0; + SmallVector DeclsToVisit; for (Decl *LexicalD : DC->decls()) { // For a friend decl, we care about the declaration within it, if any. if (auto *FD = dyn_cast(LexicalD)) @@ -105,8 +106,17 @@ if (!ND || !needsAnonymousDeclarationNumber(ND)) continue; - Visit(ND, Index++); + DeclsToVisit.push_back(ND); } + + // Decls have deterministic IDs, but they might show up in different order in + // a DeclContext. Make sure serialization gets the same order everytime by + // sorting the decls by ID. + llvm::sort(DeclsToVisit, [](const NamedDecl *L, const NamedDecl *R) { + return L->getID() < R->getID(); + }); + for (auto *ND : DeclsToVisit) + Visit(ND, Index++); } } // namespace serialization Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -3182,7 +3182,16 @@ uint64_t Offset = Stream.GetCurrentBitNo(); SmallVector KindDeclPairs; - for (const auto *D : DC->decls()) { + + // Decls have deterministic IDs, but they might show up in different order in + // a DeclContext. Make sure serialization gets the same order everytime by + // sorting the decls by ID. + SmallVector SortedDecls(DC->decls()); + llvm::sort(SortedDecls, [](const Decl *L, const Decl *R) { + return L->getID() < R->getID(); + }); + + for (const auto *D : SortedDecls) { KindDeclPairs.push_back(D->getKind()); KindDeclPairs.push_back(GetDeclRef(D)); }