aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests/Frontend/UtilsTest.cpp
blob: cf385a5323c610f249483d333d836b1d1e4f914c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//===- unittests/Frontend/UtilsTest.cpp -----------------------------------===//
//
// 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/Utils.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace clang {
namespace {
using testing::ElementsAre;

TEST(BuildCompilerInvocationTest, RecoverMultipleJobs) {
  // This generates multiple jobs and we recover by using the first.
  std::vector<const char *> Args = {"clang", "--target=macho", "-arch",  "i386",
                                    "-arch", "x86_64",         "foo.cpp"};
  clang::IgnoringDiagConsumer D;
  clang::DiagnosticOptions DiagOpts;
  CreateInvocationOptions Opts;
  Opts.RecoverOnError = true;
  Opts.VFS = new llvm::vfs::InMemoryFileSystem();
  Opts.Diags = clang::CompilerInstance::createDiagnostics(*Opts.VFS, DiagOpts,
                                                          &D, false);
  std::unique_ptr<CompilerInvocation> CI = createInvocation(Args, Opts);
  ASSERT_TRUE(CI);
  EXPECT_THAT(CI->getTargetOpts().Triple, testing::StartsWith("i386-"));
}

// buildInvocationFromCommandLine should not translate -include to -include-pch,
// even if the PCH file exists.
TEST(BuildCompilerInvocationTest, ProbePrecompiled) {
  std::vector<const char *> Args = {"clang", "-include", "foo.h", "foo.cpp"};
  auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
  FS->addFile("foo.h", 0, llvm::MemoryBuffer::getMemBuffer(""));
  FS->addFile("foo.h.pch", 0, llvm::MemoryBuffer::getMemBuffer(""));

  clang::IgnoringDiagConsumer D;
  clang::DiagnosticOptions DiagOpts;
  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine =
      clang::CompilerInstance::createDiagnostics(*FS, DiagOpts, &D, false);
  // Default: ProbePrecompiled=false
  CreateInvocationOptions CIOpts;
  CIOpts.Diags = CommandLineDiagsEngine;
  CIOpts.VFS = FS;
  std::unique_ptr<CompilerInvocation> CI = createInvocation(Args, CIOpts);
  ASSERT_TRUE(CI);
  EXPECT_THAT(CI->getPreprocessorOpts().Includes, ElementsAre("foo.h"));
  EXPECT_EQ(CI->getPreprocessorOpts().ImplicitPCHInclude, "");

  CIOpts.ProbePrecompiled = true;
  CI = createInvocation(Args, CIOpts);
  ASSERT_TRUE(CI);
  EXPECT_THAT(CI->getPreprocessorOpts().Includes, ElementsAre());
  EXPECT_EQ(CI->getPreprocessorOpts().ImplicitPCHInclude, "foo.h.pch");
}

} // namespace
} // namespace clang