Clang Project

clang_source_code/unittests/Frontend/ASTUnitTest.cpp
1//===- unittests/Frontend/ASTUnitTest.cpp - ASTUnit tests -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <fstream>
10
11#include "clang/Frontend/ASTUnit.h"
12#include "clang/Frontend/CompilerInstance.h"
13#include "clang/Frontend/CompilerInvocation.h"
14#include "clang/Frontend/PCHContainerOperations.h"
15#include "llvm/Support/FileSystem.h"
16#include "llvm/Support/Path.h"
17#include "llvm/Support/ToolOutputFile.h"
18#include "gtest/gtest.h"
19
20using namespace llvm;
21using namespace clang;
22
23namespace {
24
25class ASTUnitTest : public ::testing::Test {
26protected:
27  int FD;
28  llvm::SmallString<256InputFileName;
29  std::unique_ptr<ToolOutputFile> input_file;
30  IntrusiveRefCntPtr<DiagnosticsEngineDiags;
31  std::shared_ptr<CompilerInvocationCInvok;
32  std::shared_ptr<PCHContainerOperationsPCHContainerOps;
33
34  std::unique_ptr<ASTUnitcreateASTUnit(bool isVolatile) {
35    EXPECT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit""cpp", FD,
36                                                    InputFileName));
37    input_file = llvm::make_unique<ToolOutputFile>(InputFileName, FD);
38    input_file->os() << "";
39
40    const char *Args[] = {"clang""-xc++", InputFileName.c_str()};
41
42    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
43
44    CInvok = createInvocationFromCommandLine(Args, Diags);
45
46    if (!CInvok)
47      return nullptr;
48
49    FileManager *FileMgr =
50        new FileManager(FileSystemOptions(), vfs::getRealFileSystem());
51    PCHContainerOps = std::make_shared<PCHContainerOperations>();
52
53    return ASTUnit::LoadFromCompilerInvocation(
54        CInvok, PCHContainerOps, Diags, FileMgr, falsefalse0, TU_Complete,
55        falsefalse, isVolatile);
56  }
57};
58
59TEST_F(ASTUnitTest, SaveLoadPreservesLangOptionsInPrintingPolicy) {
60  // Check that the printing policy is restored with the correct language
61  // options when loading an ASTUnit from a file.  To this end, an ASTUnit
62  // for a C++ translation unit is set up and written to a temporary file.
63
64  // By default `UseVoidForZeroParams` is true for non-C++ language options,
65  // thus we can check this field after loading the ASTUnit to deduce whether
66  // the correct (C++) language options were used when setting up the printing
67  // policy.
68
69  {
70    PrintingPolicy PolicyWithDefaultLangOpt(LangOptions{});
71    EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams);
72  }
73
74  std::unique_ptr<ASTUnitAST = createASTUnit(false);
75
76  if (!AST)
77    FAIL() << "failed to create ASTUnit";
78
79  EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
80
81  llvm::SmallString<256ASTFileName;
82  ASSERT_FALSE(
83      llvm::sys::fs::createTemporaryFile("ast-unit""ast", FD, ASTFileName));
84  ToolOutputFile ast_file(ASTFileName, FD);
85  AST->Save(ASTFileName.str());
86
87  EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));
88
89  std::unique_ptr<ASTUnitAU = ASTUnit::LoadFromASTFile(
90      ASTFileName.str(), PCHContainerOps->getRawReader(),
91      ASTUnit::LoadEverything, Diags, FileSystemOptions(),
92      /*UseDebugInfo=*/false);
93
94  if (!AU)
95    FAIL() << "failed to load ASTUnit";
96
97  EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
98}
99
100TEST_F(ASTUnitTest, GetBufferForFileMemoryMapping) {
101  std::unique_ptr<ASTUnitAST = createASTUnit(true);
102
103  if (!AST)
104    FAIL() << "failed to create ASTUnit";
105
106  std::unique_ptr<llvm::MemoryBuffermemoryBuffer =
107      AST->getBufferForFile(InputFileName);
108
109  EXPECT_NE(memoryBuffer->getBufferKind(),
110            llvm::MemoryBuffer::MemoryBuffer_MMap);
111}
112
113// anonymous namespace
114