Index: lib/Frontend/ASTUnit.cpp =================================================================== --- lib/Frontend/ASTUnit.cpp +++ lib/Frontend/ASTUnit.cpp @@ -542,6 +542,9 @@ // Initialize the ASTContext Context->InitBuiltinTypes(*Target); + // Adjust printing policy based on language options. + Context->setPrintingPolicy(PrintingPolicy(LangOpt)); + // We didn't have access to the comment options when the ASTContext was // constructed, so register them now. Context->getCommentCommandTraits().registerCommentOptions( Index: unittests/Frontend/ASTUnitTest.cpp =================================================================== --- /dev/null +++ unittests/Frontend/ASTUnitTest.cpp @@ -0,0 +1,113 @@ +//===- unittests/Frontend/ASTUnitTest.cpp - ASTUnit tests -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include + +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/PCHContainerOperations.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace clang; + +namespace { + +class ASTUnitTest : public ::testing::Test { + std::set TemporaryFiles; + std::string TestDir; + +public: + void SetUp() override { + llvm::SmallString<256> Dir; + ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("astunit-test", Dir)); + TestDir = Dir.str(); + } + + void TearDown() override { + for (const std::string &Path : TemporaryFiles) + llvm::sys::fs::remove(Path); + llvm::sys::fs::remove(TestDir); + } + + void MarkTemporaryFile(std::string &Filename) { + assert(!llvm::sys::path::is_absolute(Filename)); + llvm::SmallString<256> Path(TestDir); + llvm::sys::path::append(Path, Filename); + Filename = Path.str(); + TemporaryFiles.insert(Filename); + llvm::sys::fs::create_directories(llvm::sys::path::parent_path(Filename)); + } +}; + +TEST_F(ASTUnitTest, SaveLoadPreservesLangOptionsInPrintingPolicy) { + // Check that the printing policy is restored with the correct language + // options when loading an ASTUnit from a file. To this end, an ASTUnit + // for a C++ translation unit is set up and written to a temporary file. + + // By default `UseVoidForZeroParams` is true for non-C++ language options, + // thus we can check this field after loading the ASTUnit to deduce whether + // the correct (C++) language options were used when setting up the printing + // policy. + + { + PrintingPolicy PolicyWithDefaultLangOpt(LangOptions{}); + EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams); + } + + std::string FileName = "empty_file.cpp"; + MarkTemporaryFile(FileName); + std::ofstream OS(FileName); + OS << ""; + ASSERT_TRUE(OS.good()); + + const char* Args[] = {"clang", "-xc++", FileName.c_str()}; + + IntrusiveRefCntPtr Diags = + CompilerInstance::createDiagnostics(new DiagnosticOptions()); + + std::shared_ptr CInvok = + createInvocationFromCommandLine(Args, Diags); + + if (!CInvok) + FAIL() << "could not create compiler invocation"; + + IntrusiveRefCntPtr VFS(new vfs::InMemoryFileSystem); + VFS->addFile(FileName, 0, llvm::MemoryBuffer::getMemBuffer("")); + FileManager *FileMgr = new FileManager(FileSystemOptions(), VFS); + auto PCHContainerOps = std::make_shared(); + + std::unique_ptr AST = ASTUnit::LoadFromCompilerInvocation( + CInvok, PCHContainerOps, Diags, FileMgr); + + if (!AST) + FAIL() << "failed to create ASTUnit"; + + EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams); + + std::string Path = "printing_policy.ast"; + MarkTemporaryFile(Path); + AST->Save(Path); + + EXPECT_TRUE(llvm::sys::fs::exists(Path)); + + std::unique_ptr AU = ASTUnit::LoadFromASTFile( + Path, PCHContainerOps->getRawReader(), ASTUnit::LoadEverything, Diags, + FileSystemOptions(), /*UseDebugInfo=*/false); + + if (!AU) + FAIL() << "failed to load ASTUnit"; + + EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams); +} + +} // anonymous namespace Index: unittests/Frontend/CMakeLists.txt =================================================================== --- unittests/Frontend/CMakeLists.txt +++ unittests/Frontend/CMakeLists.txt @@ -3,6 +3,7 @@ ) add_clang_unittest(FrontendTests + ASTUnitTest.cpp FrontendActionTest.cpp CodeGenActionTest.cpp )