brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 013aad1 Raw
121 lines · c
1//===- unittests/libclang/TestUtils.h -------------------------------------===//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#ifndef LLVM_CLANG_TEST_TESTUTILS_H10#define LLVM_CLANG_TEST_TESTUTILS_H11 12#include "clang-c/Index.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/Support/FileSystem.h"15#include "llvm/Support/Path.h"16 17#include "gtest/gtest.h"18#include <fstream>19#include <functional>20#include <memory>21#include <string>22#include <vector>23 24class LibclangParseTest : public ::testing::Test {25  typedef std::unique_ptr<std::string> fixed_addr_string;26  std::map<fixed_addr_string, fixed_addr_string> UnsavedFileContents;27public:28  // std::greater<> to remove files before their parent dirs in TearDown().29  std::set<std::string, std::greater<>> FilesAndDirsToRemove;30  std::string TestDir;31  bool RemoveTestDirRecursivelyDuringTeardown = false;32  CXIndex Index;33  CXTranslationUnit ClangTU;34  unsigned TUFlags;35  std::vector<CXUnsavedFile> UnsavedFiles;36 37  void SetUp() override {38    llvm::SmallString<256> Dir;39    ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir));40    TestDir = std::string(Dir.str());41    TUFlags = CXTranslationUnit_DetailedPreprocessingRecord |42      clang_defaultEditingTranslationUnitOptions();43    CreateIndex();44    ClangTU = nullptr;45  }46  void TearDown() override {47    clang_disposeTranslationUnit(ClangTU);48    clang_disposeIndex(Index);49 50    namespace fs = llvm::sys::fs;51    for (const std::string &Path : FilesAndDirsToRemove)52      EXPECT_FALSE(fs::remove(Path, /*IgnoreNonExisting=*/false));53    if (RemoveTestDirRecursivelyDuringTeardown)54      EXPECT_FALSE(fs::remove_directories(TestDir, /*IgnoreErrors=*/false));55    else56      EXPECT_FALSE(fs::remove(TestDir, /*IgnoreNonExisting=*/false));57  }58  void WriteFile(std::string &Filename, const std::string &Contents) {59    if (!llvm::sys::path::is_absolute(Filename)) {60      llvm::SmallString<256> Path(TestDir);61      namespace path = llvm::sys::path;62      for (auto FileI = path::begin(Filename), FileEnd = path::end(Filename);63           FileI != FileEnd; ++FileI) {64        ASSERT_NE(*FileI, ".");65        path::append(Path, *FileI);66        FilesAndDirsToRemove.emplace(Path.str());67      }68      Filename = std::string(Path.str());69    }70    llvm::sys::fs::create_directories(llvm::sys::path::parent_path(Filename));71    std::ofstream OS(Filename);72    OS << Contents;73    assert(OS.good());74  }75  void MapUnsavedFile(std::string Filename, const std::string &Contents) {76    if (!llvm::sys::path::is_absolute(Filename)) {77      llvm::SmallString<256> Path(TestDir);78      llvm::sys::path::append(Path, Filename);79      Filename = std::string(Path.str());80    }81    auto it = UnsavedFileContents.insert(std::make_pair(82        fixed_addr_string(new std::string(Filename)),83        fixed_addr_string(new std::string(Contents))));84    UnsavedFiles.push_back({85        it.first->first->c_str(),   // filename86        it.first->second->c_str(),  // contents87        it.first->second->size()    // length88    });89  }90  template <typename F>91  void Traverse(const CXCursor &cursor, const F &TraversalFunctor) {92    std::reference_wrapper<const F> FunctorRef = std::cref(TraversalFunctor);93    clang_visitChildren(cursor,94                        &TraverseStateless<std::reference_wrapper<const F>>,95                        &FunctorRef);96  }97 98  template <typename F> void Traverse(const F &TraversalFunctor) {99    Traverse(clang_getTranslationUnitCursor(ClangTU), TraversalFunctor);100  }101 102  static std::string fromCXString(CXString cx_string) {103    std::string string{clang_getCString(cx_string)};104    clang_disposeString(cx_string);105    return string;106  };107 108protected:109  virtual void CreateIndex() { Index = clang_createIndex(0, 0); }110 111private:112  template<typename TState>113  static CXChildVisitResult TraverseStateless(CXCursor cx, CXCursor parent,114      CXClientData data) {115    TState *State = static_cast<TState*>(data);116    return State->get()(cx, parent);117  }118};119 120#endif // LLVM_CLANG_TEST_TESTUTILS_H121