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 20 using namespace llvm; 21 using namespace clang; 22 23 namespace { 24 25 class ASTUnitTest : public ::testing::Test { 26 protected: 27 int FD; 28 llvm::SmallString<256> InputFileName; 29 std::unique_ptr<ToolOutputFile> input_file; 30 IntrusiveRefCntPtr<DiagnosticsEngine> Diags; 31 std::shared_ptr<CompilerInvocation> CInvok; 32 std::shared_ptr<PCHContainerOperations> PCHContainerOps; 33 34 std::unique_ptr<ASTUnit> createASTUnit(bool isVolatile) { 35 EXPECT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD, 36 InputFileName)); 37 input_file = std::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, false, CaptureDiagsKind::None, 55 0, TU_Complete, false, false, isVolatile); 56 } 57 }; 58 59 TEST_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<ASTUnit> AST = createASTUnit(false); 75 76 if (!AST) 77 FAIL() << "failed to create ASTUnit"; 78 79 EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams); 80 81 llvm::SmallString<256> ASTFileName; 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<ASTUnit> AU = 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 100 TEST_F(ASTUnitTest, GetBufferForFileMemoryMapping) { 101 std::unique_ptr<ASTUnit> AST = createASTUnit(true); 102 103 if (!AST) 104 FAIL() << "failed to create ASTUnit"; 105 106 std::unique_ptr<llvm::MemoryBuffer> memoryBuffer = 107 AST->getBufferForFile(InputFileName); 108 109 EXPECT_NE(memoryBuffer->getBufferKind(), 110 llvm::MemoryBuffer::MemoryBuffer_MMap); 111 } 112 113 } // anonymous namespace 114