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/Basic/FileManager.h" 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 class ASTUnitTest : public ::testing::Test { 27 protected: 28 int FD; 29 llvm::SmallString<256> InputFileName; 30 std::unique_ptr<ToolOutputFile> input_file; 31 IntrusiveRefCntPtr<DiagnosticsEngine> Diags; 32 std::shared_ptr<CompilerInvocation> CInvok; 33 std::shared_ptr<PCHContainerOperations> PCHContainerOps; 34 35 std::unique_ptr<ASTUnit> createASTUnit(bool isVolatile) { 36 EXPECT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD, 37 InputFileName)); 38 input_file = std::make_unique<ToolOutputFile>(InputFileName, FD); 39 input_file->os() << ""; 40 41 const char *Args[] = {"clang", "-xc++", InputFileName.c_str()}; 42 43 Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); 44 45 CInvok = createInvocationFromCommandLine(Args, Diags); 46 47 if (!CInvok) 48 return nullptr; 49 50 FileManager *FileMgr = 51 new FileManager(FileSystemOptions(), vfs::getRealFileSystem()); 52 PCHContainerOps = std::make_shared<PCHContainerOperations>(); 53 54 return ASTUnit::LoadFromCompilerInvocation( 55 CInvok, PCHContainerOps, Diags, FileMgr, false, CaptureDiagsKind::None, 56 0, TU_Complete, false, false, isVolatile); 57 } 58 }; 59 60 TEST_F(ASTUnitTest, SaveLoadPreservesLangOptionsInPrintingPolicy) { 61 // Check that the printing policy is restored with the correct language 62 // options when loading an ASTUnit from a file. To this end, an ASTUnit 63 // for a C++ translation unit is set up and written to a temporary file. 64 65 // By default `UseVoidForZeroParams` is true for non-C++ language options, 66 // thus we can check this field after loading the ASTUnit to deduce whether 67 // the correct (C++) language options were used when setting up the printing 68 // policy. 69 70 { 71 PrintingPolicy PolicyWithDefaultLangOpt(LangOptions{}); 72 EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams); 73 } 74 75 std::unique_ptr<ASTUnit> AST = createASTUnit(false); 76 77 if (!AST) 78 FAIL() << "failed to create ASTUnit"; 79 80 EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams); 81 82 llvm::SmallString<256> ASTFileName; 83 ASSERT_FALSE( 84 llvm::sys::fs::createTemporaryFile("ast-unit", "ast", FD, ASTFileName)); 85 ToolOutputFile ast_file(ASTFileName, FD); 86 AST->Save(ASTFileName.str()); 87 88 EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName)); 89 90 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile( 91 std::string(ASTFileName.str()), PCHContainerOps->getRawReader(), 92 ASTUnit::LoadEverything, Diags, FileSystemOptions(), 93 /*UseDebugInfo=*/false); 94 95 if (!AU) 96 FAIL() << "failed to load ASTUnit"; 97 98 EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams); 99 } 100 101 TEST_F(ASTUnitTest, GetBufferForFileMemoryMapping) { 102 std::unique_ptr<ASTUnit> AST = createASTUnit(true); 103 104 if (!AST) 105 FAIL() << "failed to create ASTUnit"; 106 107 std::unique_ptr<llvm::MemoryBuffer> memoryBuffer = 108 AST->getBufferForFile(InputFileName); 109 110 EXPECT_NE(memoryBuffer->getBufferKind(), 111 llvm::MemoryBuffer::MemoryBuffer_MMap); 112 } 113 114 } // anonymous namespace 115