TestUtils.h 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_CLANG_TEST_TESTUTILS_H
  9. #define LLVM_CLANG_TEST_TESTUTILS_H
  10. #include "clang-c/Index.h"
  11. #include "llvm/ADT/StringRef.h"
  12. #include "llvm/Support/FileSystem.h"
  13. #include "llvm/Support/Path.h"
  14. #include <fstream>
  15. #include <memory>
  16. #include <string>
  17. #include <vector>
  18. #include "gtest/gtest.h"
  19. class LibclangParseTest : public ::testing::Test {
  20. std::set<std::string> Files;
  21. typedef std::unique_ptr<std::string> fixed_addr_string;
  22. std::map<fixed_addr_string, fixed_addr_string> UnsavedFileContents;
  23. public:
  24. std::string TestDir;
  25. CXIndex Index;
  26. CXTranslationUnit ClangTU;
  27. unsigned TUFlags;
  28. std::vector<CXUnsavedFile> UnsavedFiles;
  29. void SetUp() override {
  30. llvm::SmallString<256> Dir;
  31. ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir));
  32. TestDir = Dir.str();
  33. TUFlags = CXTranslationUnit_DetailedPreprocessingRecord |
  34. clang_defaultEditingTranslationUnitOptions();
  35. Index = clang_createIndex(0, 0);
  36. ClangTU = nullptr;
  37. }
  38. void TearDown() override {
  39. clang_disposeTranslationUnit(ClangTU);
  40. clang_disposeIndex(Index);
  41. for (const std::string &Path : Files)
  42. llvm::sys::fs::remove(Path);
  43. llvm::sys::fs::remove(TestDir);
  44. }
  45. void WriteFile(std::string &Filename, const std::string &Contents) {
  46. if (!llvm::sys::path::is_absolute(Filename)) {
  47. llvm::SmallString<256> Path(TestDir);
  48. llvm::sys::path::append(Path, Filename);
  49. Filename = Path.str();
  50. Files.insert(Filename);
  51. }
  52. llvm::sys::fs::create_directories(llvm::sys::path::parent_path(Filename));
  53. std::ofstream OS(Filename);
  54. OS << Contents;
  55. assert(OS.good());
  56. }
  57. void MapUnsavedFile(std::string Filename, const std::string &Contents) {
  58. if (!llvm::sys::path::is_absolute(Filename)) {
  59. llvm::SmallString<256> Path(TestDir);
  60. llvm::sys::path::append(Path, Filename);
  61. Filename = Path.str();
  62. }
  63. auto it = UnsavedFileContents.insert(std::make_pair(
  64. fixed_addr_string(new std::string(Filename)),
  65. fixed_addr_string(new std::string(Contents))));
  66. UnsavedFiles.push_back({
  67. it.first->first->c_str(), // filename
  68. it.first->second->c_str(), // contents
  69. it.first->second->size() // length
  70. });
  71. }
  72. template<typename F>
  73. void Traverse(const F &TraversalFunctor) {
  74. CXCursor TuCursor = clang_getTranslationUnitCursor(ClangTU);
  75. std::reference_wrapper<const F> FunctorRef = std::cref(TraversalFunctor);
  76. clang_visitChildren(TuCursor,
  77. &TraverseStateless<std::reference_wrapper<const F>>,
  78. &FunctorRef);
  79. }
  80. private:
  81. template<typename TState>
  82. static CXChildVisitResult TraverseStateless(CXCursor cx, CXCursor parent,
  83. CXClientData data) {
  84. TState *State = static_cast<TState*>(data);
  85. return State->get()(cx, parent);
  86. }
  87. };
  88. #endif // LLVM_CLANG_TEST_TESTUTILS_H