//===- unittests/Frontend/CompilerInvocationTest.cpp - CI tests //---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "llvm/TargetParser/Host.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace clang;

using ::testing::Contains;
using ::testing::HasSubstr;
using ::testing::StrEq;
using ::testing::StartsWith;

namespace {
class CommandLineTest : public ::testing::Test {
public:
  IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
  SmallVector<const char *, 32> GeneratedArgs;
  SmallVector<std::string, 32> GeneratedArgsStorage;
  CompilerInvocation Invocation;

  const char *operator()(const Twine &Arg) {
    return GeneratedArgsStorage.emplace_back(Arg.str()).c_str();
  }

  CommandLineTest()
      : Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions(),
                                                  new TextDiagnosticBuffer())) {
  }
};

template <typename M>
std::string describeContainsN(M InnerMatcher, unsigned N, bool Negation) {
  StringRef Contains = Negation ? "doesn't contain" : "contains";
  StringRef Instance = N == 1 ? " instance " : " instances ";
  StringRef Element = "of element that ";

  std::ostringstream Inner;
  InnerMatcher.impl().DescribeTo(&Inner);

  return (Contains + " exactly " + Twine(N) + Instance + Element + Inner.str())
      .str();
}

MATCHER_P2(ContainsN, InnerMatcher, N,
           describeContainsN(InnerMatcher, N, negation)) {
  auto InnerMatches = [this](const auto &Element) {
    ::testing::internal::DummyMatchResultListener InnerListener;
    return InnerMatcher.impl().MatchAndExplain(Element, &InnerListener);
  };

  return count_if(arg, InnerMatches) == N;
}

TEST(ContainsN, Empty) {
  const char *Array[] = {""};

  ASSERT_THAT(Array, ContainsN(StrEq("x"), 0));
  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 1)));
  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 2)));
}

TEST(ContainsN, Zero) {
  const char *Array[] = {"y"};

  ASSERT_THAT(Array, ContainsN(StrEq("x"), 0));
  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 1)));
  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 2)));
}

TEST(ContainsN, One) {
  const char *Array[] = {"a", "b", "x", "z"};

  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 0)));
  ASSERT_THAT(Array, ContainsN(StrEq("x"), 1));
  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 2)));
}

TEST(ContainsN, Two) {
  const char *Array[] = {"x", "a", "b", "x"};

  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 0)));
  ASSERT_THAT(Array, Not(ContainsN(StrEq("x"), 1)));
  ASSERT_THAT(Array, ContainsN(StrEq("x"), 2));
}

// Copy constructor/assignment perform deep copy of reference-counted pointers.

TEST(CompilerInvocationTest, DeepCopyConstructor) {
  CompilerInvocation A;
  A.getAnalyzerOpts().Config["Key"] = "Old";

  CompilerInvocation B(A);
  B.getAnalyzerOpts().Config["Key"] = "New";

  ASSERT_EQ(A.getAnalyzerOpts().Config["Key"], "Old");
}

TEST(CompilerInvocationTest, DeepCopyAssignment) {
  CompilerInvocation A;
  A.getAnalyzerOpts().Config["Key"] = "Old";

  CompilerInvocation B;
  B = A;
  B.getAnalyzerOpts().Config["Key"] = "New";

  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.

TEST_F(CommandLineTest, BoolOptionDefaultTrueSingleFlagNotPresent) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getFrontendOpts().UseTemporary);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-temp-file"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultTrueSingleFlagPresent) {
  const char *Args[] = {"-fno-temp-file"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getFrontendOpts().UseTemporary);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fno-temp-file")));
}

TEST_F(CommandLineTest, CC1FlagPresentWhenDoingRoundTrip) {
  const char *Args[] = {"-cc1", "-round-trip-args"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  ASSERT_THAT(std::string(Invocation.getCodeGenOpts().CmdArgs.begin(),
                          Invocation.getCodeGenOpts().CmdArgs.end()),
              StartsWith("-cc1"));
}

TEST_F(CommandLineTest, CC1FlagPresentWhenNotDoingRoundTrip) {
  const char *Args[] = {"-cc1", "-no-round-trip-args"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  ASSERT_THAT(std::string(Invocation.getCodeGenOpts().CmdArgs.begin(),
                          Invocation.getCodeGenOpts().CmdArgs.end()),
              StartsWith("-cc1"));
}

TEST_F(CommandLineTest, BoolOptionDefaultTrueSingleFlagUnknownPresent) {
  const char *Args[] = {"-ftemp-file"};

  // Driver-only flag.
  ASSERT_FALSE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getFrontendOpts().UseTemporary);
}

// Boolean option with a keypath that defaults to true.
// The flag with negative spelling can set the keypath to false.
// The flag with positive spelling can reset the keypath to true.

TEST_F(CommandLineTest, BoolOptionDefaultTruePresentNone) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getCodeGenOpts().Autolink);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fautolink"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-autolink"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultTruePresentNegChange) {
  const char *Args[] = {"-fno-autolink"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getCodeGenOpts().Autolink);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fno-autolink")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fautolink"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultTruePresentPosReset) {
  const char *Args[] = {"-fautolink"};

  // Driver-only flag.
  ASSERT_FALSE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getCodeGenOpts().Autolink);
}

// Boolean option with a keypath that defaults to false.
// The flag with negative spelling can set the keypath to true.
// The flag with positive spelling can reset the keypath to false.

TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNone) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getCodeGenOpts().NoInlineLineTables);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-ginline-line-tables"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gno-inline-line-tables"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNegChange) {
  const char *Args[] = {"-gno-inline-line-tables"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getCodeGenOpts().NoInlineLineTables);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-gno-inline-line-tables")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-ginline-line-tables"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentPosReset) {
  const char *Args[] = {"-ginline-line-tables"};

  // Driver-only flag.
  ASSERT_FALSE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getCodeGenOpts().NoInlineLineTables);
}

// Boolean option with a keypath that defaults to false.
// The flag with positive spelling can set the keypath to true.
// The flag with negative spelling can reset the keypath to false.

TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNoneX) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getCodeGenOpts().CodeViewGHash);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gcodeview-ghash"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gno-codeview-ghash"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentPosChange) {
  const char *Args[] = {"-gcodeview-ghash"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getCodeGenOpts().CodeViewGHash);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-gcodeview-ghash")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gno-codeview-ghash"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNegReset) {
  const char *Args[] = {"-gno-codeview-ghash"};

  // Driver-only flag.
  ASSERT_FALSE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getCodeGenOpts().CodeViewGHash);
}

// Boolean option with a keypath that defaults to an arbitrary expression.
// The flag with positive spelling can set the keypath to true.
// The flag with negative spelling can set the keypath to false.

TEST_F(CommandLineTest, BoolOptionDefaultArbitraryTwoFlagsPresentNone) {
  const char *Args = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getCodeGenOpts().ClearASTBeforeBackend, false);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-no-clear-ast-before-backend"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-clear-ast-before-backend"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultArbitraryTwoFlagsPresentChange) {
  const char *Args[] = {"-clear-ast-before-backend"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getCodeGenOpts().ClearASTBeforeBackend, true);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-clear-ast-before-backend")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-no-clear-ast-before-backend"))));
}

TEST_F(CommandLineTest, BoolOptionDefaultArbitraryTwoFlagsPresentReset) {
  const char *Args[] = {"-no-clear-ast-before-backend"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getCodeGenOpts().ClearASTBeforeBackend, false);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-no-clear-ast-before-backend"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-clear-ast-before-backend"))));
}

// Boolean option that gets the CC1Option flag from a let statement (which
// is applied **after** the record is defined):
//
//   let Flags = [CC1Option] in {
//     defm option : BoolOption<...>;
//   }

TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentNone) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getCodeGenOpts().DebugPassManager);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdebug-pass-manager"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager"))));
}

TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentPos) {
  const char *Args[] = {"-fdebug-pass-manager"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getCodeGenOpts().DebugPassManager);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, ContainsN(StrEq("-fdebug-pass-manager"), 1));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager"))));
}

TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentNeg) {
  const char *Args[] = {"-fno-debug-pass-manager"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getCodeGenOpts().DebugPassManager);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdebug-pass-manager"))));
}

TEST_F(CommandLineTest, CanGenerateCC1CommandLineFlag) {
  const char *Args[] = {"-fmodules-strict-context-hash"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fmodules-strict-context-hash")));
}

TEST_F(CommandLineTest, CanGenerateCC1CommandLineSeparate) {
  const char *TripleCStr = "i686-apple-darwin9";
  const char *Args[] = {"-triple", TripleCStr};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq(TripleCStr)));
}

TEST_F(CommandLineTest,  CanGenerateCC1CommandLineSeparateRequiredPresent) {
  const std::string DefaultTriple =
      llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple());
  const char *Args[] = {"-triple", DefaultTriple.c_str()};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Triple should always be emitted even if it is the default
  ASSERT_THAT(GeneratedArgs, Contains(StrEq(DefaultTriple.c_str())));
}

TEST_F(CommandLineTest, CanGenerateCC1CommandLineSeparateRequiredAbsent) {
  const std::string DefaultTriple =
      llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple());
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Triple should always be emitted even if it is the default
  ASSERT_THAT(GeneratedArgs, Contains(StrEq(DefaultTriple.c_str())));
}

TEST_F(CommandLineTest, SeparateEnumNonDefault) {
  const char *Args[] = {"-mrelocation-model", "static"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getCodeGenOpts().RelocationModel, Reloc::Model::Static);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Non default relocation model.
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-mrelocation-model")));
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("static")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-mrelocation-model=static"))));
}

TEST_F(CommandLineTest, SeparateEnumDefault) {
  const char *Args[] = {"-mrelocation-model", "pic"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getCodeGenOpts().RelocationModel, Reloc::Model::PIC_);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Default relocation model.
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-mrelocation-model"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("pic"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-mrelocation-model=pic"))));
}

TEST_F(CommandLineTest, JoinedEnumNonDefault) {
  const char *Args[] = {"-fobjc-dispatch-method=non-legacy"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getCodeGenOpts().getObjCDispatchMethod(),
            CodeGenOptions::NonLegacy);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs,
              Contains(StrEq("-fobjc-dispatch-method=non-legacy")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fobjc-dispatch-method="))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("non-legacy"))));
}

TEST_F(CommandLineTest, JoinedEnumDefault) {
  const char *Args[] = {"-fobjc-dispatch-method=legacy"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getCodeGenOpts().getObjCDispatchMethod(),
            CodeGenOptions::Legacy);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs,
              Not(Contains(StrEq("-fobjc-dispatch-method=legacy"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fobjc-dispatch-method="))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("legacy"))));
}

TEST_F(CommandLineTest, StringVectorEmpty) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getFrontendOpts().ModuleMapFiles.empty());

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-fmodule-map-file"))));
}

TEST_F(CommandLineTest, StringVectorSingle) {
  const char *Args[] = {"-fmodule-map-file=a"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getFrontendOpts().ModuleMapFiles,
            std::vector<std::string>({"a"}));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, ContainsN(StrEq("-fmodule-map-file=a"), 1));
  ASSERT_THAT(GeneratedArgs, ContainsN(HasSubstr("-fmodule-map-file"), 1));
}

TEST_F(CommandLineTest, StringVectorMultiple) {
  const char *Args[] = {"-fmodule-map-file=a", "-fmodule-map-file=b"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getFrontendOpts().ModuleMapFiles ==
              std::vector<std::string>({"a", "b"}));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, ContainsN(StrEq("-fmodule-map-file=a"), 1));
  ASSERT_THAT(GeneratedArgs, ContainsN(StrEq("-fmodule-map-file=b"), 1));
  ASSERT_THAT(GeneratedArgs, ContainsN(HasSubstr("-fmodule-map-file"), 2));
}

// CommaJoined option with MarshallingInfoStringVector.

TEST_F(CommandLineTest, StringVectorCommaJoinedNone) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getLangOpts().CommentOpts.BlockCommandNames.empty());

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs,
              Not(Contains(HasSubstr("-fcomment-block-commands"))));
}

TEST_F(CommandLineTest, StringVectorCommaJoinedSingle) {
  const char *Args[] = {"-fcomment-block-commands=x,y"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getLangOpts().CommentOpts.BlockCommandNames,
            std::vector<std::string>({"x", "y"}));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs,
              ContainsN(StrEq("-fcomment-block-commands=x,y"), 1));
}

TEST_F(CommandLineTest, StringVectorCommaJoinedMultiple) {
  const char *Args[] = {"-fcomment-block-commands=x,y",
                        "-fcomment-block-commands=a,b"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_EQ(Invocation.getLangOpts().CommentOpts.BlockCommandNames,
            std::vector<std::string>({"x", "y", "a", "b"}));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs,
              ContainsN(StrEq("-fcomment-block-commands=x,y,a,b"), 1));
}

// A flag that should be parsed only if a condition is met.

TEST_F(CommandLineTest, ConditionalParsingIfFalseFlagNotPresent) {
  const char *Args[] = {""};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsDevice);
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsHost);
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(), LangOptions::SYCL_None);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std="))));
}

TEST_F(CommandLineTest, ConditionalParsingIfFalseFlagPresent) {
  const char *Args[] = {"-sycl-std=2017"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsDevice);
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsHost);
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(), LangOptions::SYCL_None);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-device"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-host"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std="))));
}

TEST_F(CommandLineTest, ConditionalParsingIfNonsenseSyclStdArg) {
  const char *Args[] = {"-fsycl-is-device", "-sycl-std=garbage"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_TRUE(Diags->hasErrorOccurred());
  ASSERT_TRUE(Invocation.getLangOpts().SYCLIsDevice);
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsHost);
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(), LangOptions::SYCL_None);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-device")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-host"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std="))));
}

TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg1) {
  const char *Args[] = {"-fsycl-is-device", "-sycl-std=121"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_TRUE(Invocation.getLangOpts().SYCLIsDevice);
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsHost);
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(), LangOptions::SYCL_2017);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-device")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-host"))));
  ASSERT_THAT(GeneratedArgs, Contains(HasSubstr("-sycl-std=2017")));
}

TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg2) {
  const char *Args[] = {"-fsycl-is-device", "-sycl-std=1.2.1"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_TRUE(Invocation.getLangOpts().SYCLIsDevice);
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsHost);
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(), LangOptions::SYCL_2017);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-device")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-host"))));
  ASSERT_THAT(GeneratedArgs, Contains(HasSubstr("-sycl-std=2017")));
}

TEST_F(CommandLineTest, ConditionalParsingIfOddSyclStdArg3) {
  const char *Args[] = {"-fsycl-is-device", "-sycl-std=sycl-1.2.1"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_TRUE(Invocation.getLangOpts().SYCLIsDevice);
  ASSERT_FALSE(Invocation.getLangOpts().SYCLIsHost);
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(), LangOptions::SYCL_2017);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-device")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl-is-host"))));
  ASSERT_THAT(GeneratedArgs, Contains(HasSubstr("-sycl-std=2017")));
}

TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresentHost) {
  const char *Args[] = {"-fsycl-is-host"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(),
            LangOptions::SYCL_Default);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-host")));
  ASSERT_THAT(GeneratedArgs, Contains(HasSubstr("-sycl-std=")));
}

TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresentDevice) {
  const char *Args[] = {"-fsycl-is-device"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(),
            LangOptions::SYCL_Default);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-device")));
  ASSERT_THAT(GeneratedArgs, Contains(HasSubstr("-sycl-std=")));
}

TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagPresent) {
  const char *Args[] = {"-fsycl-is-device", "-sycl-std=2017"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_EQ(Invocation.getLangOpts().getSYCLVersion(), LangOptions::SYCL_2017);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl-is-device")));
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-sycl-std=2017")));
}

// Wide integer option.

TEST_F(CommandLineTest, WideIntegerHighValue) {
  const char *Args[] = {"-fbuild-session-timestamp=1609827494445723662"};

  CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);

  ASSERT_FALSE(Diags->hasErrorOccurred());
  ASSERT_EQ(Invocation.getHeaderSearchOpts().BuildSessionTimestamp,
            1609827494445723662ull);
}

// Tree of boolean options that can be (directly or transitively) implied by
// their parent:
//
//   * -cl-unsafe-math-optimizations
//     * -cl-mad-enable
//     * -funsafe-math-optimizations
//       * -freciprocal-math

TEST_F(CommandLineTest, ImpliedBoolOptionsNoFlagPresent) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getLangOpts().CLUnsafeMath);
  ASSERT_FALSE(Invocation.getCodeGenOpts().LessPreciseFPMAD);
  ASSERT_FALSE(Invocation.getLangOpts().UnsafeFPMath);
  ASSERT_FALSE(Invocation.getLangOpts().AllowRecip);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Not generated - missing.
  ASSERT_THAT(GeneratedArgs,
              Not(Contains(StrEq("-cl-unsafe-math-optimizations"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable"))));
  ASSERT_THAT(GeneratedArgs,
              Not(Contains(StrEq("-funsafe-math-optimizations"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math"))));
}

TEST_F(CommandLineTest, ImpliedBoolOptionsRootFlagPresent) {
  const char *Args[] = {"-cl-unsafe-math-optimizations"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  // Explicitly provided root flag.
  ASSERT_TRUE(Invocation.getLangOpts().CLUnsafeMath);
  // Directly implied by explicitly provided root flag.
  ASSERT_TRUE(Invocation.getCodeGenOpts().LessPreciseFPMAD);
  ASSERT_TRUE(Invocation.getLangOpts().UnsafeFPMath);
  // Transitively implied by explicitly provided root flag.
  ASSERT_TRUE(Invocation.getLangOpts().AllowRecip);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Generated - explicitly provided.
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-unsafe-math-optimizations")));
  // Not generated - implied by the generated root flag.
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable"))));
  ASSERT_THAT(GeneratedArgs,
              Not(Contains(StrEq("-funsafe-math-optimizations"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math"))));
}

TEST_F(CommandLineTest, ImpliedBoolOptionsAllFlagsPresent) {
  const char *Args[] = {"-cl-unsafe-math-optimizations", "-cl-mad-enable",
                        "-funsafe-math-optimizations", "-freciprocal-math"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getLangOpts().CLUnsafeMath);
  ASSERT_TRUE(Invocation.getCodeGenOpts().LessPreciseFPMAD);
  ASSERT_TRUE(Invocation.getLangOpts().UnsafeFPMath);
  ASSERT_TRUE(Invocation.getLangOpts().AllowRecip);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Generated - explicitly provided.
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-unsafe-math-optimizations")));
  // Not generated - implied by their generated parent.
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable"))));
  ASSERT_THAT(GeneratedArgs,
              Not(Contains(StrEq("-funsafe-math-optimizations"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math"))));
}

TEST_F(CommandLineTest, ImpliedBoolOptionsImpliedFlagsPresent) {
  const char *Args[] = {"-cl-mad-enable", "-funsafe-math-optimizations",
                        "-freciprocal-math"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getLangOpts().CLUnsafeMath);
  ASSERT_TRUE(Invocation.getCodeGenOpts().LessPreciseFPMAD);
  ASSERT_TRUE(Invocation.getLangOpts().UnsafeFPMath);
  ASSERT_TRUE(Invocation.getLangOpts().AllowRecip);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  // Not generated - missing.
  ASSERT_THAT(GeneratedArgs,
              Not(Contains(StrEq("-cl-unsafe-math-optimizations"))));
  // Generated - explicitly provided.
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-mad-enable")));
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-funsafe-math-optimizations")));
  // Not generated - implied by its generated parent.
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math"))));
}

TEST_F(CommandLineTest, PresentAndNotImpliedGenerated) {
  const char *Args[] = {"-cl-mad-enable", "-funsafe-math-optimizations"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  // Present options that were not implied are generated.
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-mad-enable")));
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-funsafe-math-optimizations")));
}

// Diagnostic option.

TEST_F(CommandLineTest, DiagnosticOptionPresent) {
  const char *Args[] = {"-verify=xyz"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  ASSERT_EQ(Invocation.getDiagnosticOpts().VerifyPrefixes,
            std::vector<std::string>({"xyz"}));

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs, ContainsN(StrEq("-verify=xyz"), 1));
}

// Option default depends on language standard.

TEST_F(CommandLineTest, DigraphsImplied) {
  const char *Args[] = {""};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getLangOpts().Digraphs);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-digraphs"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdigraphs"))));
}

TEST_F(CommandLineTest, DigraphsDisabled) {
  const char *Args[] = {"-fno-digraphs"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getLangOpts().Digraphs);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fno-digraphs")));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdigraphs"))));
}

TEST_F(CommandLineTest, DigraphsNotImplied) {
  const char *Args[] = {"-std=c89"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_FALSE(Invocation.getLangOpts().Digraphs);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-digraphs"))));
  ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdigraphs"))));
}

TEST_F(CommandLineTest, DigraphsEnabled) {
  const char *Args[] = {"-std=c89", "-fdigraphs"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_TRUE(Invocation.getLangOpts().Digraphs);

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);
  ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fdigraphs")));
}

struct DummyModuleFileExtension
    : public llvm::RTTIExtends<DummyModuleFileExtension, ModuleFileExtension> {
  static char ID;

  ModuleFileExtensionMetadata getExtensionMetadata() const override {
    return {};
  };

  void hashExtension(ExtensionHashBuilder &HBuilder) const override {}

  std::unique_ptr<ModuleFileExtensionWriter>
  createExtensionWriter(ASTWriter &Writer) override {
    return {};
  }

  std::unique_ptr<ModuleFileExtensionReader>
  createExtensionReader(const ModuleFileExtensionMetadata &Metadata,
                        ASTReader &Reader, serialization::ModuleFile &Mod,
                        const llvm::BitstreamCursor &Stream) override {
    return {};
  }
};

char DummyModuleFileExtension::ID = 0;

TEST_F(CommandLineTest, TestModuleFileExtension) {
  const char *Args[] = {"-ftest-module-file-extension=first:2:1:0:first",
                        "-ftest-module-file-extension=second:3:2:1:second"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
  ASSERT_THAT(Invocation.getFrontendOpts().ModuleFileExtensions.size(), 2);

  // Exercise the check that only serializes instances of
  // TestModuleFileExtension by providing an instance of another
  // ModuleFileExtension subclass.
  Invocation.getFrontendOpts().ModuleFileExtensions.push_back(
      std::make_shared<DummyModuleFileExtension>());

  Invocation.generateCC1CommandLine(GeneratedArgs, *this);

  ASSERT_THAT(GeneratedArgs,
              ContainsN(HasSubstr("-ftest-module-file-extension="), 2));
  ASSERT_THAT(
      GeneratedArgs,
      Contains(StrEq("-ftest-module-file-extension=first:2:1:0:first")));
  ASSERT_THAT(
      GeneratedArgs,
      Contains(StrEq("-ftest-module-file-extension=second:3:2:1:second")));
}

TEST_F(CommandLineTest, RoundTrip) {
  // Testing one marshalled and one manually generated option from each
  // CompilerInvocation member.
  const char *Args[] = {
      "-round-trip-args",
      // LanguageOptions
      "-std=c17",
      "-fmax-tokens=10",
      // TargetOptions
      "-target-sdk-version=1.2.3",
      "-meabi",
      "4",
      // DiagnosticOptions
      "-Wundef-prefix=XY",
      "-fdiagnostics-format",
      "clang",
      // HeaderSearchOptions
      "-stdlib=libc++",
      "-fimplicit-module-maps",
      // PreprocessorOptions
      "-DXY=AB",
      "-include-pch",
      "a.pch",
      // AnalyzerOptions
      "-analyzer-config",
      "ctu-import-threshold=42",
      "-unoptimized-cfg",
      // MigratorOptions (no manually handled arguments)
      "-no-ns-alloc-error",
      // CodeGenOptions
      "-debug-info-kind=limited",
      "-debug-info-macro",
      // DependencyOutputOptions
      "--show-includes",
      "-H",
      // FileSystemOptions (no manually handled arguments)
      "-working-directory",
      "folder",
      // FrontendOptions
      "-load",
      "plugin",
      "-ast-merge",
      // PreprocessorOutputOptions
      "-dD",
      "-CC",
  };

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));

  ASSERT_TRUE(Invocation.getLangOpts().C17);
  ASSERT_EQ(Invocation.getLangOpts().MaxTokens, 10u);

  ASSERT_EQ(Invocation.getTargetOpts().SDKVersion, llvm::VersionTuple(1, 2, 3));
  ASSERT_EQ(Invocation.getTargetOpts().EABIVersion, EABI::EABI4);

  ASSERT_THAT(Invocation.getDiagnosticOpts().UndefPrefixes,
              Contains(StrEq("XY")));
  ASSERT_EQ(Invocation.getDiagnosticOpts().getFormat(),
            TextDiagnosticFormat::Clang);

  ASSERT_TRUE(Invocation.getHeaderSearchOpts().UseLibcxx);
  ASSERT_TRUE(Invocation.getHeaderSearchOpts().ImplicitModuleMaps);

  ASSERT_THAT(Invocation.getPreprocessorOpts().Macros,
              Contains(std::make_pair(std::string("XY=AB"), false)));
  ASSERT_EQ(Invocation.getPreprocessorOpts().ImplicitPCHInclude, "a.pch");

  ASSERT_EQ(Invocation.getAnalyzerOpts().Config["ctu-import-threshold"], "42");
  ASSERT_TRUE(Invocation.getAnalyzerOpts().UnoptimizedCFG);

  ASSERT_TRUE(Invocation.getMigratorOpts().NoNSAllocReallocError);

  ASSERT_EQ(Invocation.getCodeGenOpts().getDebugInfo(),
            codegenoptions::DebugInfoKind::LimitedDebugInfo);
  ASSERT_TRUE(Invocation.getCodeGenOpts().MacroDebugInfo);

  ASSERT_EQ(Invocation.getDependencyOutputOpts().ShowIncludesDest,
            ShowIncludesDestination::Stdout);
  ASSERT_TRUE(Invocation.getDependencyOutputOpts().ShowHeaderIncludes);
}

TEST_F(CommandLineTest, PluginArgsRoundTripDeterminism) {
  const char *Args[] = {
      "-plugin-arg-blink-gc-plugin", "no-members-in-stack-allocated",
      "-plugin-arg-find-bad-constructs", "checked-ptr-as-trivial-member",
      "-plugin-arg-find-bad-constructs", "check-ipc",
      // Enable round-trip to ensure '-plugin-arg' generation is deterministic.
      "-round-trip-args"};

  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags));
}
} // anonymous namespace
