[llvm-c] Simplify signature of LLVMGetTargetFromName
[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/TargetRegistry.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include "llvm/Support/Host.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 NULL;
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   for (TargetRegistry::iterator IT = TargetRegistry::begin(),
77                                 IE = TargetRegistry::end(); IT != IE; ++IT) {
78     if (IT->getName() == Name)
79       return wrap(&*IT);
80   }
81   
82   return NULL;
83 }
84
85 LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
86                                  char **ErrorMessage) {
87   std::string Error;
88   
89   *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
90   
91   if (!*T) {
92     if (ErrorMessage)
93       *ErrorMessage = strdup(Error.c_str());
94
95     return 1;
96   }
97   
98   return 0;
99 }
100
101 const char * LLVMGetTargetName(LLVMTargetRef T) {
102   return unwrap(T)->getName();
103 }
104
105 const char * LLVMGetTargetDescription(LLVMTargetRef T) {
106   return unwrap(T)->getShortDescription();
107 }
108
109 LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
110   return unwrap(T)->hasJIT();
111 }
112
113 LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
114   return unwrap(T)->hasTargetMachine();
115 }
116
117 LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
118   return unwrap(T)->hasMCAsmBackend();
119 }
120
121 LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char* Triple,
122   char* CPU, char* Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
123   LLVMCodeModel CodeModel) {
124   Reloc::Model RM;
125   switch (Reloc){
126     case LLVMRelocStatic:
127       RM = Reloc::Static;
128       break;
129     case LLVMRelocPIC:
130       RM = Reloc::PIC_;
131       break;
132     case LLVMRelocDynamicNoPic:
133       RM = Reloc::DynamicNoPIC;
134       break;
135     default:
136       RM = Reloc::Default;
137       break;
138   }
139
140   CodeModel::Model CM = unwrap(CodeModel);
141
142   CodeGenOpt::Level OL;
143   switch (Level) {
144     case LLVMCodeGenLevelNone:
145       OL = CodeGenOpt::None;
146       break;
147     case LLVMCodeGenLevelLess:
148       OL = CodeGenOpt::Less;
149       break;
150     case LLVMCodeGenLevelAggressive:
151       OL = CodeGenOpt::Aggressive;
152       break;
153     default:
154       OL = CodeGenOpt::Default;
155       break;
156   }
157
158   TargetOptions opt;
159   return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
160     CM, OL));
161 }
162
163
164 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
165   delete unwrap(T);
166 }
167
168 LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
169   const Target* target = &(unwrap(T)->getTarget());
170   return wrap(target);
171 }
172
173 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
174   std::string StringRep = unwrap(T)->getTargetTriple();
175   return strdup(StringRep.c_str());
176 }
177
178 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
179   std::string StringRep = unwrap(T)->getTargetCPU();
180   return strdup(StringRep.c_str());
181 }
182
183 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
184   std::string StringRep = unwrap(T)->getTargetFeatureString();
185   return strdup(StringRep.c_str());
186 }
187
188 LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
189   return wrap(unwrap(T)->getDataLayout());
190 }
191
192 void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
193                                       LLVMBool VerboseAsm) {
194   unwrap(T)->setAsmVerbosityDefault(VerboseAsm);
195 }
196
197 static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
198   formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) {
199   TargetMachine* TM = unwrap(T);
200   Module* Mod = unwrap(M);
201
202   PassManager pass;
203
204   std::string error;
205
206   const DataLayout* td = TM->getDataLayout();
207
208   if (!td) {
209     error = "No DataLayout in TargetMachine";
210     *ErrorMessage = strdup(error.c_str());
211     return true;
212   }
213   pass.add(new DataLayout(*td));
214
215   TargetMachine::CodeGenFileType ft;
216   switch (codegen) {
217     case LLVMAssemblyFile:
218       ft = TargetMachine::CGFT_AssemblyFile;
219       break;
220     default:
221       ft = TargetMachine::CGFT_ObjectFile;
222       break;
223   }
224   if (TM->addPassesToEmitFile(pass, OS, ft)) {
225     error = "TargetMachine can't emit a file of this type";
226     *ErrorMessage = strdup(error.c_str());
227     return true;
228   }
229
230   pass.run(*Mod);
231
232   OS.flush();
233   return false;
234 }
235
236 LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
237   char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
238   std::string error;
239   raw_fd_ostream dest(Filename, error, sys::fs::F_Binary);
240   if (!error.empty()) {
241     *ErrorMessage = strdup(error.c_str());
242     return true;
243   }
244   formatted_raw_ostream destf(dest);
245   bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
246   dest.flush();
247   return Result;
248 }
249
250 LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
251   LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
252   LLVMMemoryBufferRef *OutMemBuf) {
253   std::string CodeString;
254   raw_string_ostream OStream(CodeString);
255   formatted_raw_ostream Out(OStream);
256   bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
257   OStream.flush();
258
259   std::string &Data = OStream.str();
260   *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(),
261                                                      Data.length(), "");
262   return Result;
263 }
264
265 char *LLVMGetDefaultTargetTriple(void) {
266   return strdup(sys::getDefaultTargetTriple().c_str());
267 }