1 //===- unittests/Frontend/ASTUnitTest.cpp - ASTUnit tests -----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <fstream>
11 
12 #include "clang/Frontend/ASTUnit.h"
13 #include "clang/Frontend/CompilerInstance.h"
14 #include "clang/Frontend/CompilerInvocation.h"
15 #include "clang/Frontend/PCHContainerOperations.h"
16 #include "llvm/Support/FileSystem.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/ToolOutputFile.h"
19 #include "gtest/gtest.h"
20 
21 using namespace llvm;
22 using namespace clang;
23 
24 namespace {
25 
26 TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
27   // Check that the printing policy is restored with the correct language
28   // options when loading an ASTUnit from a file.  To this end, an ASTUnit
29   // for a C++ translation unit is set up and written to a temporary file.
30 
31   // By default `UseVoidForZeroParams` is true for non-C++ language options,
32   // thus we can check this field after loading the ASTUnit to deduce whether
33   // the correct (C++) language options were used when setting up the printing
34   // policy.
35 
36   {
37     PrintingPolicy PolicyWithDefaultLangOpt(LangOptions{});
38     EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams);
39   }
40 
41   int FD;
42   llvm::SmallString<256> InputFileName;
43   ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD, InputFileName));
44   ToolOutputFile input_file(InputFileName, FD);
45   input_file.os() << "";
46 
47   const char* Args[] = {"clang", "-xc++", InputFileName.c_str()};
48 
49   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
50       CompilerInstance::createDiagnostics(new DiagnosticOptions());
51 
52   std::shared_ptr<CompilerInvocation> CInvok =
53       createInvocationFromCommandLine(Args, Diags);
54 
55   if (!CInvok)
56     FAIL() << "could not create compiler invocation";
57 
58   FileManager *FileMgr =
59       new FileManager(FileSystemOptions(), vfs::getRealFileSystem());
60   auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
61 
62   std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
63       CInvok, PCHContainerOps, Diags, FileMgr);
64 
65   if (!AST)
66     FAIL() << "failed to create ASTUnit";
67 
68   EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
69 
70   llvm::SmallString<256> ASTFileName;
71   ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "ast", FD, ASTFileName));
72   ToolOutputFile ast_file(ASTFileName, FD);
73   AST->Save(ASTFileName.str());
74 
75   EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));
76 
77   std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
78       ASTFileName.str(), PCHContainerOps->getRawReader(), ASTUnit::LoadEverything, Diags,
79       FileSystemOptions(), /*UseDebugInfo=*/false);
80 
81   if (!AU)
82     FAIL() << "failed to load ASTUnit";
83 
84   EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
85 }
86 
87 } // anonymous namespace
88