1 | //===- ARCMigrate.cpp - Clang-C ARC Migration Library ---------------------===// |
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 | // |
9 | // This file implements the main API hooks in the Clang-C ARC Migration library. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang-c/Index.h" |
14 | #include "CXString.h" |
15 | #include "clang/ARCMigrate/ARCMT.h" |
16 | #include "clang/Config/config.h" |
17 | #include "clang/Frontend/TextDiagnosticBuffer.h" |
18 | #include "llvm/Support/FileSystem.h" |
19 | |
20 | using namespace clang; |
21 | using namespace arcmt; |
22 | |
23 | namespace { |
24 | |
25 | struct Remap { |
26 | std::vector<std::pair<std::string, std::string> > Vec; |
27 | }; |
28 | |
29 | } // anonymous namespace. |
30 | |
31 | //===----------------------------------------------------------------------===// |
32 | // libClang public APIs. |
33 | //===----------------------------------------------------------------------===// |
34 | |
35 | CXRemapping clang_getRemappings(const char *migrate_dir_path) { |
36 | #if !CLANG_ENABLE_ARCMT |
37 | llvm::errs() << "error: feature not enabled in this build\n" ; |
38 | return nullptr; |
39 | #else |
40 | bool Logging = ::getenv(name: "LIBCLANG_LOGGING" ); |
41 | |
42 | if (!migrate_dir_path) { |
43 | if (Logging) |
44 | llvm::errs() << "clang_getRemappings was called with NULL parameter\n" ; |
45 | return nullptr; |
46 | } |
47 | |
48 | if (!llvm::sys::fs::exists(Path: migrate_dir_path)) { |
49 | if (Logging) { |
50 | llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path |
51 | << "\")\n" ; |
52 | llvm::errs() << "\"" << migrate_dir_path << "\" does not exist\n" ; |
53 | } |
54 | return nullptr; |
55 | } |
56 | |
57 | TextDiagnosticBuffer diagBuffer; |
58 | std::unique_ptr<Remap> remap(new Remap()); |
59 | |
60 | bool err = arcmt::getFileRemappings(remap&: remap->Vec, outputDir: migrate_dir_path,DiagClient: &diagBuffer); |
61 | |
62 | if (err) { |
63 | if (Logging) { |
64 | llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path |
65 | << "\")\n" ; |
66 | for (TextDiagnosticBuffer::const_iterator |
67 | I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I) |
68 | llvm::errs() << I->second << '\n'; |
69 | } |
70 | return nullptr; |
71 | } |
72 | |
73 | return remap.release(); |
74 | #endif |
75 | } |
76 | |
77 | CXRemapping clang_getRemappingsFromFileList(const char **filePaths, |
78 | unsigned numFiles) { |
79 | #if !CLANG_ENABLE_ARCMT |
80 | llvm::errs() << "error: feature not enabled in this build\n" ; |
81 | return nullptr; |
82 | #else |
83 | bool Logging = ::getenv(name: "LIBCLANG_LOGGING" ); |
84 | |
85 | std::unique_ptr<Remap> remap(new Remap()); |
86 | |
87 | if (numFiles == 0) { |
88 | if (Logging) |
89 | llvm::errs() << "clang_getRemappingsFromFileList was called with " |
90 | "numFiles=0\n" ; |
91 | return remap.release(); |
92 | } |
93 | |
94 | if (!filePaths) { |
95 | if (Logging) |
96 | llvm::errs() << "clang_getRemappingsFromFileList was called with " |
97 | "NULL filePaths\n" ; |
98 | return nullptr; |
99 | } |
100 | |
101 | TextDiagnosticBuffer diagBuffer; |
102 | SmallVector<StringRef, 32> Files(filePaths, filePaths + numFiles); |
103 | |
104 | bool err = arcmt::getFileRemappingsFromFileList(remap&: remap->Vec, remapFiles: Files, |
105 | DiagClient: &diagBuffer); |
106 | |
107 | if (err) { |
108 | if (Logging) { |
109 | llvm::errs() << "Error by clang_getRemappingsFromFileList\n" ; |
110 | for (TextDiagnosticBuffer::const_iterator |
111 | I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I) |
112 | llvm::errs() << I->second << '\n'; |
113 | } |
114 | return remap.release(); |
115 | } |
116 | |
117 | return remap.release(); |
118 | #endif |
119 | } |
120 | |
121 | unsigned clang_remap_getNumFiles(CXRemapping map) { |
122 | return static_cast<Remap *>(map)->Vec.size(); |
123 | |
124 | } |
125 | |
126 | void clang_remap_getFilenames(CXRemapping map, unsigned index, |
127 | CXString *original, CXString *transformed) { |
128 | if (original) |
129 | *original = cxstring::createDup( |
130 | String: static_cast<Remap *>(map)->Vec[index].first); |
131 | if (transformed) |
132 | *transformed = cxstring::createDup( |
133 | String: static_cast<Remap *>(map)->Vec[index].second); |
134 | } |
135 | |
136 | void clang_remap_dispose(CXRemapping map) { |
137 | delete static_cast<Remap *>(map); |
138 | } |
139 | |