From e1cc299ec885d0b1607f162322fe23b772866acf Mon Sep 17 00:00:00 2001 From: Jan Svoboda Date: Thu, 7 Sep 2023 14:01:40 -0700 Subject: [clang] Introduce copy-on-write `CompilerInvocation` (#65412) This PR introduces new copy-on-write `CompilerInvocation` class (`CowCompilerInvocation`), which will be used by the dependency scanner to reduce the number of copies performed when generating command lines for discovered modules. --- .../unittests/Frontend/CompilerInvocationTest.cpp | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'clang/unittests/Frontend/CompilerInvocationTest.cpp') diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp index 36a2eda..7912253 100644 --- a/clang/unittests/Frontend/CompilerInvocationTest.cpp +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -121,6 +121,46 @@ TEST(CompilerInvocationTest, DeepCopyAssignment) { ASSERT_EQ(A.getAnalyzerOpts().Config["Key"], "Old"); } +TEST(CompilerInvocationTest, CopyOnWriteConstructor) { + CowCompilerInvocation A; + A.getMutFrontendOpts().OutputFile = "x.o"; + + // B's FrontendOptions are initially shared with A. + CowCompilerInvocation B(A); + EXPECT_EQ(&A.getFrontendOpts(), &B.getFrontendOpts()); + + // Modifying A's FrontendOptions creates new copy, does not affect other opts. + A.getMutFrontendOpts().OutputFile = "y.o"; + EXPECT_NE(&A.getFrontendOpts(), &B.getFrontendOpts()); + EXPECT_EQ(&A.getCodeGenOpts(), &B.getCodeGenOpts()); + + // The new copy reflects the modification, old instance remains unchanged. + EXPECT_EQ(A.getFrontendOpts().OutputFile, "y.o"); + EXPECT_EQ(B.getFrontendOpts().OutputFile, "x.o"); +} + +TEST(CompilerInvocationTest, CopyOnWriteAssignment) { + CowCompilerInvocation A; + A.getMutFrontendOpts().OutputFile = "x.o"; + + // B's FrontendOptions are initially independent of A. + CowCompilerInvocation B; + EXPECT_NE(&A.getFrontendOpts(), &B.getFrontendOpts()); + + // B's FrontendOptions are shared with A after assignment. + B = A; + EXPECT_EQ(&A.getFrontendOpts(), &B.getFrontendOpts()); + + // Modifying A's FrontendOptions creates new copy, does not affect other opts. + A.getMutFrontendOpts().OutputFile = "y.o"; + EXPECT_NE(&A.getFrontendOpts(), &B.getFrontendOpts()); + EXPECT_EQ(&A.getCodeGenOpts(), &B.getCodeGenOpts()); + + // The new copy reflects the modification, old instance remains unchanged. + EXPECT_EQ(A.getFrontendOpts().OutputFile, "y.o"); + EXPECT_EQ(B.getFrontendOpts().OutputFile, "x.o"); +} + // Boolean option with a keypath that defaults to true. // The only flag with a negative spelling can set the keypath to false. -- cgit v1.1