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