yaml::Input::mapTag(): Don't use StringRef to hold return type of std::string.
[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 LLVMBool LLVMGetTargetFromName(const char *Name, LLVMTargetRef *T) {
76   for (TargetRegistry::iterator IT = TargetRegistry::begin(),
77                                 IE = TargetRegistry::end(); IT != IE; ++IT) {
78     if (IT->getName() == Name) {
79       *T = wrap(&*IT);
80
81       return 0;
82     }
83   }
84   
85   return 1;
86 }
87
88 LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
89                                  char **ErrorMessage) {
90   std::string Error;
91   
92   *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
93   
94   if (!*T) {
95     if (ErrorMessage)
96       *ErrorMessage = strdup(Error.c_str());
97
98     return 1;
99   }
100   
101   return 0;
102 }
103
104 const char * LLVMGetTargetName(LLVMTargetRef T) {
105   return unwrap(T)->getName();
106 }
107
108 const char * LLVMGetTargetDescription(LLVMTargetRef T) {
109   return unwrap(T)->getShortDescription();
110 }
111
112 LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
113   return unwrap(T)->hasJIT();
114 }
115
116 LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
117   return unwrap(T)->hasTargetMachine();
118 }
119
120 LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
121   return unwrap(T)->hasMCAsmBackend();
122 }
123
124 LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char* Triple,
125   char* CPU, char* Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
126   LLVMCodeModel CodeModel) {
127   Reloc::Model RM;
128   switch (Reloc){
129     case LLVMRelocStatic:
130       RM = Reloc::Static;
131       break;
132     case LLVMRelocPIC:
133       RM = Reloc::PIC_;
134       break;
135     case LLVMRelocDynamicNoPic:
136       RM = Reloc::DynamicNoPIC;
137       break;
138     default:
139       RM = Reloc::Default;
140       break;
141   }
142
143   CodeModel::Model CM = unwrap(CodeModel);
144
145   CodeGenOpt::Level OL;
146   switch (Level) {
147     case LLVMCodeGenLevelNone:
148       OL = CodeGenOpt::None;
149       break;
150     case LLVMCodeGenLevelLess:
151       OL = CodeGenOpt::Less;
152       break;
153     case LLVMCodeGenLevelAggressive:
154       OL = CodeGenOpt::Aggressive;
155       break;
156     default:
157       OL = CodeGenOpt::Default;
158       break;
159   }
160
161   TargetOptions opt;
162   return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
163     CM, OL));
164 }
165
166
167 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
168   delete unwrap(T);
169 }
170
171 LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
172   const Target* target = &(unwrap(T)->getTarget());
173   return wrap(target);
174 }
175
176 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
177   std::string StringRep = unwrap(T)->getTargetTriple();
178   return strdup(StringRep.c_str());
179 }
180
181 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
182   std::string StringRep = unwrap(T)->getTargetCPU();
183   return strdup(StringRep.c_str());
184 }
185
186 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
187   std::string StringRep = unwrap(T)->getTargetFeatureString();
188   return strdup(StringRep.c_str());
189 }
190
191 LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
192   return wrap(unwrap(T)->getDataLayout());
193 }
194
195 void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
196                                       LLVMBool VerboseAsm) {
197   unwrap(T)->setAsmVerbosityDefault(VerboseAsm);
198 }
199
200 static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
201   formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) {
202   TargetMachine* TM = unwrap(T);
203   Module* Mod = unwrap(M);
204
205   PassManager pass;
206
207   std::string error;
208
209   const DataLayout* td = TM->getDataLayout();
210
211   if (!td) {
212     error = "No DataLayout in TargetMachine";
213     *ErrorMessage = strdup(error.c_str());
214     return true;
215   }
216   pass.add(new DataLayout(*td));
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_Binary);
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 }