[C++] Use 'nullptr'. Target edition.
[oota-llvm.git] / lib / Target / TargetMachineC.cpp
1 //===-- TargetMachine.cpp -------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the LLVM-C part of TargetMachine.h
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm-c/TargetMachine.h"
15 #include "llvm-c/Core.h"
16 #include "llvm-c/Target.h"
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/PassManager.h"
20 #include "llvm/Support/CodeGen.h"
21 #include "llvm/Support/FormattedStream.h"
22 #include "llvm/Support/Host.h"
23 #include "llvm/Support/TargetRegistry.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/Target/TargetMachine.h"
26 #include <cassert>
27 #include <cstdlib>
28 #include <cstring>
29
30 using namespace llvm;
31
32 inline DataLayout *unwrap(LLVMTargetDataRef P) {
33   return reinterpret_cast<DataLayout*>(P);
34 }
35
36 inline LLVMTargetDataRef wrap(const DataLayout *P) {
37   return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
38 }
39
40 inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
41   return reinterpret_cast<TargetLibraryInfo*>(P);
42 }
43
44 inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
45   TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
46   return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
47 }
48
49 inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
50   return reinterpret_cast<TargetMachine*>(P);
51 }
52 inline Target *unwrap(LLVMTargetRef P) {
53   return reinterpret_cast<Target*>(P);
54 }
55 inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
56   return
57     reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
58 }
59 inline LLVMTargetRef wrap(const Target * P) {
60   return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
61 }
62
63 LLVMTargetRef LLVMGetFirstTarget() {
64   if(TargetRegistry::begin() == TargetRegistry::end()) {
65     return nullptr;
66   }
67
68   const Target* target = &*TargetRegistry::begin();
69   return wrap(target);
70 }
71 LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
72   return wrap(unwrap(T)->getNext());
73 }
74
75 LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
76   StringRef NameRef = Name;
77   for (TargetRegistry::iterator IT = TargetRegistry::begin(),
78                                 IE = TargetRegistry::end(); IT != IE; ++IT) {
79     if (IT->getName() == NameRef)
80       return wrap(&*IT);
81   }
82   
83   return nullptr;
84 }
85
86 LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
87                                  char **ErrorMessage) {
88   std::string Error;
89   
90   *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
91   
92   if (!*T) {
93     if (ErrorMessage)
94       *ErrorMessage = strdup(Error.c_str());
95
96     return 1;
97   }
98   
99   return 0;
100 }
101
102 const char * LLVMGetTargetName(LLVMTargetRef T) {
103   return unwrap(T)->getName();
104 }
105
106 const char * LLVMGetTargetDescription(LLVMTargetRef T) {
107   return unwrap(T)->getShortDescription();
108 }
109
110 LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
111   return unwrap(T)->hasJIT();
112 }
113
114 LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
115   return unwrap(T)->hasTargetMachine();
116 }
117
118 LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
119   return unwrap(T)->hasMCAsmBackend();
120 }
121
122 LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
123         const char* Triple, const char* CPU, const char* Features,
124         LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
125         LLVMCodeModel CodeModel) {
126   Reloc::Model RM;
127   switch (Reloc){
128     case LLVMRelocStatic:
129       RM = Reloc::Static;
130       break;
131     case LLVMRelocPIC:
132       RM = Reloc::PIC_;
133       break;
134     case LLVMRelocDynamicNoPic:
135       RM = Reloc::DynamicNoPIC;
136       break;
137     default:
138       RM = Reloc::Default;
139       break;
140   }
141
142   CodeModel::Model CM = unwrap(CodeModel);
143
144   CodeGenOpt::Level OL;
145   switch (Level) {
146     case LLVMCodeGenLevelNone:
147       OL = CodeGenOpt::None;
148       break;
149     case LLVMCodeGenLevelLess:
150       OL = CodeGenOpt::Less;
151       break;
152     case LLVMCodeGenLevelAggressive:
153       OL = CodeGenOpt::Aggressive;
154       break;
155     default:
156       OL = CodeGenOpt::Default;
157       break;
158   }
159
160   TargetOptions opt;
161   return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
162     CM, OL));
163 }
164
165
166 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
167   delete unwrap(T);
168 }
169
170 LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
171   const Target* target = &(unwrap(T)->getTarget());
172   return wrap(target);
173 }
174
175 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
176   std::string StringRep = unwrap(T)->getTargetTriple();
177   return strdup(StringRep.c_str());
178 }
179
180 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
181   std::string StringRep = unwrap(T)->getTargetCPU();
182   return strdup(StringRep.c_str());
183 }
184
185 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
186   std::string StringRep = unwrap(T)->getTargetFeatureString();
187   return strdup(StringRep.c_str());
188 }
189
190 LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
191   return wrap(unwrap(T)->getDataLayout());
192 }
193
194 void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
195                                       LLVMBool VerboseAsm) {
196   unwrap(T)->setAsmVerbosityDefault(VerboseAsm);
197 }
198
199 static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
200   formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) {
201   TargetMachine* TM = unwrap(T);
202   Module* Mod = unwrap(M);
203
204   PassManager pass;
205
206   std::string error;
207
208   const DataLayout* td = TM->getDataLayout();
209
210   if (!td) {
211     error = "No DataLayout in TargetMachine";
212     *ErrorMessage = strdup(error.c_str());
213     return true;
214   }
215   Mod->setDataLayout(td);
216   pass.add(new DataLayoutPass(Mod));
217
218   TargetMachine::CodeGenFileType ft;
219   switch (codegen) {
220     case LLVMAssemblyFile:
221       ft = TargetMachine::CGFT_AssemblyFile;
222       break;
223     default:
224       ft = TargetMachine::CGFT_ObjectFile;
225       break;
226   }
227   if (TM->addPassesToEmitFile(pass, OS, ft)) {
228     error = "TargetMachine can't emit a file of this type";
229     *ErrorMessage = strdup(error.c_str());
230     return true;
231   }
232
233   pass.run(*Mod);
234
235   OS.flush();
236   return false;
237 }
238
239 LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
240   char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
241   std::string error;
242   raw_fd_ostream dest(Filename, error, sys::fs::F_None);
243   if (!error.empty()) {
244     *ErrorMessage = strdup(error.c_str());
245     return true;
246   }
247   formatted_raw_ostream destf(dest);
248   bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
249   dest.flush();
250   return Result;
251 }
252
253 LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
254   LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
255   LLVMMemoryBufferRef *OutMemBuf) {
256   std::string CodeString;
257   raw_string_ostream OStream(CodeString);
258   formatted_raw_ostream Out(OStream);
259   bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
260   OStream.flush();
261
262   std::string &Data = OStream.str();
263   *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(),
264                                                      Data.length(), "");
265   return Result;
266 }
267
268 char *LLVMGetDefaultTargetTriple(void) {
269   return strdup(sys::getDefaultTargetTriple().c_str());
270 }
271
272 void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
273   unwrap(T)->addAnalysisPasses(*unwrap(PM));
274 }