steven_wu updated this revision to Diff 489150. steven_wu added a comment. @akyrtzi has the good idea. It is really hard to control `Decl*` to get values to get an unstable iteration order from the small tests, going beyond 32 decls to get out of SmallPtrSet's small model is much consistent.
Add test. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D141625/new/ https://reviews.llvm.org/D141625 Files: clang/lib/Parse/ParseDecl.cpp clang/test/Modules/decl-params-determinisim.m Index: clang/test/Modules/decl-params-determinisim.m =================================================================== --- /dev/null +++ clang/test/Modules/decl-params-determinisim.m @@ -0,0 +1,67 @@ +// RUN: rm -rf %t.dir +// RUN: split-file %s %t.dir +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.dir/cache -triple x86_64-apple-macosx10.11.0 \ +// RUN: -I%t.dir/headers %t.dir/main.m -fdisable-module-hash -Wno-visibility +// RUN: mv %t.dir/cache/A.pcm %t1.pcm +// RUN: rm -rf %t.dir/cache +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.dir/cache -triple x86_64-apple-macosx10.11.0 \ +// RUN: -I%t.dir/headers %t.dir/main.m -fdisable-module-hash -Wno-visibility +// RUN: mv %t.dir/cache/A.pcm %t2.pcm +// RUN: diff %t1.pcm %t2.pcm + +//--- headers/a.h +void f(struct A1 *a0, + struct A1 *a1, + struct A2 *a2, + struct A3 *a3, + struct A4 *a4, + struct A5 *a5, + struct A6 *a6, + struct A7 *a7, + struct A8 *a8, + struct A9 *a9, + struct A10 *a10, + struct A11 *a11, + struct A12 *a12, + struct A13 *a13, + struct A14 *a14, + struct A15 *a15, + struct A16 *a16, + struct A17 *a17, + struct A18 *a18, + struct A19 *a19, + struct A20 *a20, + struct A21 *a21, + struct A22 *a22, + struct A23 *a23, + struct A24 *a24, + struct A25 *a25, + struct A26 *a26, + struct A27 *a27, + struct A28 *a28, + struct A29 *a29, + struct A30 *a30, + struct A31 *a31, + struct A32 *a32, + struct A33 *a33, + struct A34 *a34, + struct A35 *a35, + struct A36 *a36, + struct A37 *a37, + struct A38 *a38, + struct A39 *a39, + struct A40 *a40); + + +//--- headers/module.modulemap + +module A { + header "a.h" +} + +//--- main.m + +#import <a.h> + Index: clang/lib/Parse/ParseDecl.cpp =================================================================== --- clang/lib/Parse/ParseDecl.cpp +++ clang/lib/Parse/ParseDecl.cpp @@ -6986,6 +6986,15 @@ continue; DeclsInPrototype.push_back(ND); } + // Sort DeclsInPrototype based on raw encoding of the source location. + // Scope::decls() is iterating over a SmallPtrSet so sort the Decls before + // moving to DeclContext. This provides a stable ordering for traversing + // Decls in DeclContext, which is important for tasks like ASTWriter for + // deterministic output. + llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) { + return D1->getLocation().getRawEncoding() < + D2->getLocation().getRawEncoding(); + }); } // Remember that we parsed a function type, and remember the attributes.
Index: clang/test/Modules/decl-params-determinisim.m =================================================================== --- /dev/null +++ clang/test/Modules/decl-params-determinisim.m @@ -0,0 +1,67 @@ +// RUN: rm -rf %t.dir +// RUN: split-file %s %t.dir +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.dir/cache -triple x86_64-apple-macosx10.11.0 \ +// RUN: -I%t.dir/headers %t.dir/main.m -fdisable-module-hash -Wno-visibility +// RUN: mv %t.dir/cache/A.pcm %t1.pcm +// RUN: rm -rf %t.dir/cache +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.dir/cache -triple x86_64-apple-macosx10.11.0 \ +// RUN: -I%t.dir/headers %t.dir/main.m -fdisable-module-hash -Wno-visibility +// RUN: mv %t.dir/cache/A.pcm %t2.pcm +// RUN: diff %t1.pcm %t2.pcm + +//--- headers/a.h +void f(struct A1 *a0, + struct A1 *a1, + struct A2 *a2, + struct A3 *a3, + struct A4 *a4, + struct A5 *a5, + struct A6 *a6, + struct A7 *a7, + struct A8 *a8, + struct A9 *a9, + struct A10 *a10, + struct A11 *a11, + struct A12 *a12, + struct A13 *a13, + struct A14 *a14, + struct A15 *a15, + struct A16 *a16, + struct A17 *a17, + struct A18 *a18, + struct A19 *a19, + struct A20 *a20, + struct A21 *a21, + struct A22 *a22, + struct A23 *a23, + struct A24 *a24, + struct A25 *a25, + struct A26 *a26, + struct A27 *a27, + struct A28 *a28, + struct A29 *a29, + struct A30 *a30, + struct A31 *a31, + struct A32 *a32, + struct A33 *a33, + struct A34 *a34, + struct A35 *a35, + struct A36 *a36, + struct A37 *a37, + struct A38 *a38, + struct A39 *a39, + struct A40 *a40); + + +//--- headers/module.modulemap + +module A { + header "a.h" +} + +//--- main.m + +#import <a.h> + Index: clang/lib/Parse/ParseDecl.cpp =================================================================== --- clang/lib/Parse/ParseDecl.cpp +++ clang/lib/Parse/ParseDecl.cpp @@ -6986,6 +6986,15 @@ continue; DeclsInPrototype.push_back(ND); } + // Sort DeclsInPrototype based on raw encoding of the source location. + // Scope::decls() is iterating over a SmallPtrSet so sort the Decls before + // moving to DeclContext. This provides a stable ordering for traversing + // Decls in DeclContext, which is important for tasks like ASTWriter for + // deterministic output. + llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) { + return D1->getLocation().getRawEncoding() < + D2->getLocation().getRawEncoding(); + }); } // Remember that we parsed a function type, and remember the attributes.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits