• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 google llc
2 //
3 // licensed under the apache license, version 2.0 (the "license");
4 // you may not use this file except in compliance with the license.
5 // you may obtain a copy of the license at
6 //
7 //     http://www.apache.org/licenses/license-2.0
8 //
9 // unless required by applicable law or agreed to in writing, software
10 // distributed under the license is distributed on an "as is" basis,
11 // without warranties or conditions of any kind, either express or implied.
12 // see the license for the specific language governing permissions and
13 // limitations under the license.
14 
15 #include "sandboxed_api/tools/clang_generator/frontend_action_test_util.h"
16 
17 #include <algorithm>
18 #include <iterator>
19 #include <memory>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include "absl/container/flat_hash_map.h"
25 #include "absl/status/status.h"
26 #include "absl/strings/ascii.h"
27 #include "absl/strings/str_cat.h"
28 #include "absl/strings/str_replace.h"
29 #include "absl/strings/string_view.h"
30 #include "clang/Basic/FileManager.h"
31 #include "clang/Basic/FileSystemOptions.h"
32 #include "clang/Frontend/FrontendAction.h"
33 #include "clang/Tooling/Tooling.h"
34 #include "llvm/ADT/IntrusiveRefCntPtr.h"
35 #include "llvm/ADT/StringRef.h"
36 #include "llvm/Config/llvm-config.h"
37 #include "llvm/Support/MemoryBuffer.h"
38 #include "llvm/Support/VirtualFileSystem.h"
39 
40 namespace sapi {
41 namespace internal {
42 
RunClangTool(const std::vector<std::string> & command_line,const absl::flat_hash_map<std::string,std::string> & file_contents,std::unique_ptr<clang::FrontendAction> action)43 absl::Status RunClangTool(
44     const std::vector<std::string>& command_line,
45     const absl::flat_hash_map<std::string, std::string>& file_contents,
46     std::unique_ptr<clang::FrontendAction> action) {
47   // Setup an in-memory virtual filesystem
48   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> fs(
49       new llvm::vfs::InMemoryFileSystem());
50   llvm::IntrusiveRefCntPtr<clang::FileManager> files =
51       new clang::FileManager(clang::FileSystemOptions(), fs);
52 
53   for (const auto& [filename, content] : file_contents) {
54     if (!fs->addFile(filename, /*ModificationTime=*/0,
55                      llvm::MemoryBuffer::getMemBuffer(content))) {
56       return absl::UnknownError(
57           absl::StrCat("Couldn't add file to in-memory VFS: ", filename));
58     }
59   }
60 
61 #if LLVM_VERSION_MAJOR >= 10
62   clang::tooling::ToolInvocation invocation(command_line, std::move(action),
63                                             files.get());
64 #else
65   clang::tooling::ToolInvocation invocation(command_line, action.get(),
66                                             files.get());
67 #endif
68   if (!invocation.run()) {
69     return absl::UnknownError("Tool invocation failed");
70   }
71   return absl::OkStatus();
72 }
73 
74 }  // namespace internal
75 
GetCommandLineFlagsForTesting(absl::string_view input_file)76 std::vector<std::string> FrontendActionTest::GetCommandLineFlagsForTesting(
77     absl::string_view input_file) {
78   return {"tool", "-fsyntax-only", "--std=c++17",
79           "-I.",  "-Wno-error",    std::string(input_file)};
80 }
81 
Uglify(absl::string_view code)82 std::string Uglify(absl::string_view code) {
83   std::string result = absl::StrReplaceAll(code, {{"\n", " "}});
84   absl::RemoveExtraAsciiWhitespace(&result);
85   return result;
86 }
87 
UglifyAll(const std::vector<std::string> & snippets)88 std::vector<std::string> UglifyAll(const std::vector<std::string>& snippets) {
89   std::vector<std::string> result;
90   result.reserve(snippets.size());
91   std::transform(snippets.cbegin(), snippets.cend(), std::back_inserter(result),
92                  Uglify);
93   return result;
94 }
95 
96 }  // namespace sapi
97