brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 6b34b96 Raw
124 lines · cpp
1//====-- unittests/Frontend/ReparseWorkingDirTest.cpp - FrontendAction 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/Basic/Diagnostic.h"10#include "clang/Basic/FileManager.h"11#include "clang/Frontend/ASTUnit.h"12#include "clang/Frontend/CompilerInstance.h"13#include "clang/Frontend/CompilerInvocation.h"14#include "clang/Frontend/FrontendActions.h"15#include "clang/Frontend/FrontendOptions.h"16#include "clang/Lex/PreprocessorOptions.h"17#include "llvm/Support/FileSystem.h"18#include "llvm/Support/MemoryBuffer.h"19#include "llvm/Support/Path.h"20#include "gtest/gtest.h"21 22using namespace llvm;23using namespace clang;24 25namespace {26class ReparseWorkingDirTest : public ::testing::Test {27  IntrusiveRefCntPtr<vfs::InMemoryFileSystem> VFS;28  std::shared_ptr<PCHContainerOperations> PCHContainerOpts;29 30public:31  void SetUp() override {32    VFS = llvm::makeIntrusiveRefCnt<vfs::InMemoryFileSystem>();33  }34  void TearDown() override {}35 36  void setWorkingDirectory(StringRef Path) {37    VFS->setCurrentWorkingDirectory(Path);38  }39 40  void AddFile(const std::string &Filename, const std::string &Contents) {41    ::time_t now;42    ::time(&now);43    VFS->addFile(Filename, now,44                 MemoryBuffer::getMemBufferCopy(Contents, Filename));45  }46 47  std::unique_ptr<ASTUnit> ParseAST(StringRef EntryFile) {48    PCHContainerOpts = std::make_shared<PCHContainerOperations>();49    auto CI = std::make_shared<CompilerInvocation>();50    CI->getFrontendOpts().Inputs.push_back(FrontendInputFile(51        EntryFile, FrontendOptions::getInputKindForExtension(52                       llvm::sys::path::extension(EntryFile).substr(1))));53 54    CI->getHeaderSearchOpts().AddPath("headers",55                                      frontend::IncludeDirGroup::Quoted,56                                      /*isFramework*/ false,57                                      /*IgnoreSysRoot*/ false);58 59    CI->getFileSystemOpts().WorkingDir = *VFS->getCurrentWorkingDirectory();60    CI->getTargetOpts().Triple = "i386-unknown-linux-gnu";61 62    auto DiagOpts = std::make_shared<DiagnosticOptions>();63    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(64        CompilerInstance::createDiagnostics(*VFS, *DiagOpts,65                                            new DiagnosticConsumer));66 67    auto FileMgr =68        llvm::makeIntrusiveRefCnt<FileManager>(CI->getFileSystemOpts(), VFS);69 70    std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(71        CI, PCHContainerOpts, DiagOpts, Diags, FileMgr, false,72        CaptureDiagsKind::None,73        /*PrecompilePreambleAfterNParses=*/1);74    return AST;75  }76 77  bool ReparseAST(const std::unique_ptr<ASTUnit> &AST) {78    bool reparseFailed =79        AST->Reparse(PCHContainerOpts, /*RemappedFiles*/ {}, VFS);80    return !reparseFailed;81  }82};83 84TEST_F(ReparseWorkingDirTest, ReparseWorkingDir) {85  // Setup the working directory path.86  SmallString<16> WorkingDir;87#ifdef _WIN3288  WorkingDir = "C:\\";89#else90  WorkingDir = "/";91#endif92  llvm::sys::path::append(WorkingDir, "root");93  setWorkingDirectory(WorkingDir);94 95  SmallString<32> Header;96  llvm::sys::path::append(Header, WorkingDir, "headers", "header.h");97 98  SmallString<32> MainName;99  llvm::sys::path::append(MainName, WorkingDir, "main.cpp");100 101  AddFile(MainName.str().str(), R"cpp(102#include "header.h"103int main() { return foo(); }104)cpp");105  AddFile(Header.str().str(), R"h(106static int foo() { return 0; }107)h");108 109  // Parse the main file, ensuring we can include the header.110  std::unique_ptr<ASTUnit> AST(ParseAST(MainName.str()));111  ASSERT_TRUE(AST.get());112  ASSERT_FALSE(AST->getDiagnostics().hasErrorOccurred());113 114  // Reparse and check that the working directory was preserved.115  ASSERT_TRUE(ReparseAST(AST));116 117  const auto &FM = AST->getFileManager();118  const auto &FS = FM.getVirtualFileSystem();119  ASSERT_EQ(FM.getFileSystemOpts().WorkingDir, WorkingDir);120  ASSERT_EQ(*FS.getCurrentWorkingDirectory(), WorkingDir);121}122 123} // end anonymous namespace124