blob: 630abecbd0c24299dbeac7678884666532a4bffa [file] [log] [blame]
Chris Lattner16c7bb22002-05-09 02:28:59 +00001//===-- Writer.cpp - Library for writing C files --------------------------===//
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00002//
3// This library implements the functionality defined in llvm/Assembly/CWriter.h
4// and CLocalVars.h
5//
6// TODO : Recursive types.
Chris Lattner16c7bb22002-05-09 02:28:59 +00007//
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00008//===-----------------------------------------------------------------------==//
Chris Lattner16c7bb22002-05-09 02:28:59 +00009
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000010#include "llvm/Assembly/CWriter.h"
11#include "CLocalVars.h"
12#include "llvm/SlotCalculator.h"
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000013#include "llvm/Constants.h"
Chris Lattner2f5f51a2002-05-09 03:28:37 +000014#include "llvm/DerivedTypes.h"
15#include "llvm/Module.h"
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000016#include "llvm/GlobalVariable.h"
Chris Lattner2f5f51a2002-05-09 03:28:37 +000017#include "llvm/Function.h"
18#include "llvm/Argument.h"
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000019#include "llvm/BasicBlock.h"
20#include "llvm/iMemory.h"
21#include "llvm/iTerminators.h"
22#include "llvm/iPHINode.h"
23#include "llvm/iOther.h"
Chris Lattner2f5f51a2002-05-09 03:28:37 +000024#include "llvm/iOperators.h"
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000025#include "llvm/SymbolTable.h"
26#include "llvm/Support/InstVisitor.h"
27#include "Support/StringExtras.h"
28#include "Support/STLExtras.h"
29
30#include <algorithm>
31#include <strstream>
32using std::string;
33using std::map;
34using std::vector;
35using std::ostream;
36
Chris Lattner16c7bb22002-05-09 02:28:59 +000037//===-----------------------------------------------------------------------==//
38//
39// Implementation of the CLocalVars methods
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000040
41// Appends a variable to the LocalVars map if it does not already exist
42// Also check that the type exists on the map.
43void CLocalVars::addLocalVar(const Type *t, const string & var) {
44 if (!LocalVars.count(t) ||
45 find(LocalVars[t].begin(), LocalVars[t].end(), var)
46 == LocalVars[t].end()) {
47 LocalVars[t].push_back(var);
48 }
49}
50
Chris Lattner16c7bb22002-05-09 02:28:59 +000051static string calcTypeNameVar(const Type *Ty,
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000052 map<const Type *, string> &TypeNames,
53 string VariableName, string NameSoFar);
54
55static std::string getConstStrValue(const Constant* CPV);
56
57
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000058// We dont want identifier names with ., space, - in them.
59// So we replace them with _
60static string makeNameProper(string x) {
61 string tmp;
62 for (string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++) {
63 if (*sI == '.')
64 tmp += '_';
65 else if (*sI == ' ')
66 tmp += '_';
67 else if (*sI == '-')
68 tmp += "__";
69 else
70 tmp += *sI;
71 }
72 return tmp;
73}
74
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000075static std::string getConstArrayStrValue(const Constant* CPV) {
76 std::string Result;
77
78 // As a special case, print the array as a string if it is an array of
79 // ubytes or an array of sbytes with positive values.
80 //
81 const Type *ETy = cast<ArrayType>(CPV->getType())->getElementType();
82 bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
83
84 if (ETy == Type::SByteTy) {
85 for (unsigned i = 0; i < CPV->getNumOperands(); ++i)
86 if (ETy == Type::SByteTy &&
87 cast<ConstantSInt>(CPV->getOperand(i))->getValue() < 0) {
88 isString = false;
89 break;
90 }
91 }
Chris Lattner2f5eb4e2002-05-09 03:56:52 +000092 if (isString) {
93 // Make sure the last character is a null char, as automatically added by C
94 if (CPV->getNumOperands() == 0 ||
95 !cast<Constant>(*(CPV->op_end()-1))->isNullValue())
96 isString = false;
97 }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +000098
99 if (isString) {
100 Result = "\"";
Chris Lattner2f5eb4e2002-05-09 03:56:52 +0000101 // Do not include the last character, which we know is null
102 for (unsigned i = 0, e = CPV->getNumOperands()-1; i != e; ++i) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000103 unsigned char C = (ETy == Type::SByteTy) ?
104 (unsigned char)cast<ConstantSInt>(CPV->getOperand(i))->getValue() :
105 (unsigned char)cast<ConstantUInt>(CPV->getOperand(i))->getValue();
106
107 if (isprint(C)) {
108 Result += C;
109 } else {
Chris Lattner2f5eb4e2002-05-09 03:56:52 +0000110 switch (C) {
111 case '\n': Result += "\\n"; break;
112 case '\t': Result += "\\t"; break;
113 case '\r': Result += "\\r"; break;
114 case '\v': Result += "\\v"; break;
115 case '\a': Result += "\\a"; break;
116 default:
117 Result += "\\x";
118 Result += ( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A');
119 Result += ((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A');
120 break;
121 }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000122 }
123 }
124 Result += "\"";
125
126 } else {
127 Result = "{";
128 if (CPV->getNumOperands()) {
129 Result += " " + getConstStrValue(cast<Constant>(CPV->getOperand(0)));
130 for (unsigned i = 1; i < CPV->getNumOperands(); i++)
131 Result += ", " + getConstStrValue(cast<Constant>(CPV->getOperand(i)));
132 }
133 Result += " }";
134 }
135
136 return Result;
137}
138
139static std::string getConstStructStrValue(const Constant* CPV) {
140 std::string Result = "{";
141 if (CPV->getNumOperands()) {
142 Result += " " + getConstStrValue(cast<Constant>(CPV->getOperand(0)));
143 for (unsigned i = 1; i < CPV->getNumOperands(); i++)
144 Result += ", " + getConstStrValue(cast<Constant>(CPV->getOperand(i)));
145 }
146
147 return Result + " }";
148}
149
150// our own getStrValue function for constant initializers
151static std::string getConstStrValue(const Constant* CPV) {
152 // Does not handle null pointers, that needs to be checked explicitly
153 string tempstr;
154 if (CPV == ConstantBool::False)
155 return "0";
156 else if (CPV == ConstantBool::True)
157 return "1";
158
159 else if (isa<ConstantArray>(CPV)) {
160 tempstr = getConstArrayStrValue(CPV);
161 }
162 else if (isa<ConstantStruct>(CPV)) {
163 tempstr = getConstStructStrValue(CPV);
164 }
165 else if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(CPV)) {
Chris Lattner16c7bb22002-05-09 02:28:59 +0000166 tempstr = utostr(CUI->getValue());
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000167 }
168 else if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(CPV)) {
169 tempstr = itostr(CSI->getValue());
170 }
171 else if (ConstantFP *CFP = dyn_cast<ConstantFP>(CPV)) {
172 tempstr = ftostr(CFP->getValue());
173 }
174
175 if (CPV->getType() == Type::ULongTy)
176 tempstr += "ull";
177 else if (CPV->getType() == Type::LongTy)
178 tempstr += "ll";
179 else if (CPV->getType() == Type::UIntTy ||
180 CPV->getType() == Type::UShortTy)
181 tempstr += "u";
182
183 return tempstr;
184
185}
186
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000187// Internal function
188// Essentially pass the Type* variable, an empty typestack and this prints
189// out the C type
Chris Lattner16c7bb22002-05-09 02:28:59 +0000190static string calcTypeName(const Type *Ty, map<const Type *, string> &TypeNames,
191 string &FunctionInfo) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000192
193 // Takin' care of the fact that boolean would be int in C
194 // and that ushort would be unsigned short etc.
195
196 // Base Case
197 if (Ty->isPrimitiveType())
198 switch (Ty->getPrimitiveID()) {
Chris Lattner16c7bb22002-05-09 02:28:59 +0000199 case Type::VoidTyID: return "void";
200 case Type::BoolTyID: return "bool";
201 case Type::UByteTyID: return "unsigned char";
202 case Type::SByteTyID: return "signed char";
203 case Type::UShortTyID: return "unsigned short";
204 case Type::ShortTyID: return "short";
205 case Type::UIntTyID: return "unsigned";
206 case Type::IntTyID: return "int";
207 case Type::ULongTyID: return "unsigned long long";
208 case Type::LongTyID: return "signed long long";
209 case Type::FloatTyID: return "float";
210 case Type::DoubleTyID: return "double";
211 default : assert(0 && "Unknown primitive type!");
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000212 }
213
214 // Check to see if the type is named.
215 map<const Type *, string>::iterator I = TypeNames.find(Ty);
216 if (I != TypeNames.end())
217 return I->second;
218
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000219 string Result;
220 string MInfo = "";
221 switch (Ty->getPrimitiveID()) {
222 case Type::FunctionTyID: {
223 const FunctionType *MTy = cast<const FunctionType>(Ty);
Chris Lattner16c7bb22002-05-09 02:28:59 +0000224 Result = calcTypeName(MTy->getReturnType(), TypeNames, MInfo);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000225 if (MInfo != "")
226 Result += ") " + MInfo;
227 Result += "(";
Chris Lattner16c7bb22002-05-09 02:28:59 +0000228 FunctionInfo += " (";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000229 for (FunctionType::ParamTypes::const_iterator
230 I = MTy->getParamTypes().begin(),
231 E = MTy->getParamTypes().end(); I != E; ++I) {
232 if (I != MTy->getParamTypes().begin())
Chris Lattner16c7bb22002-05-09 02:28:59 +0000233 FunctionInfo += ", ";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000234 MInfo = "";
Chris Lattner16c7bb22002-05-09 02:28:59 +0000235 FunctionInfo += calcTypeName(*I, TypeNames, MInfo);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000236 if (MInfo != "")
237 Result += ") " + MInfo;
238 }
239 if (MTy->isVarArg()) {
240 if (!MTy->getParamTypes().empty())
Chris Lattner16c7bb22002-05-09 02:28:59 +0000241 FunctionInfo += ", ";
242 FunctionInfo += "...";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000243 }
Chris Lattner16c7bb22002-05-09 02:28:59 +0000244 FunctionInfo += ")";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000245 break;
246 }
247 case Type::StructTyID: {
248 string tempstr = "";
249 const StructType *STy = cast<const StructType>(Ty);
250 Result = " struct {\n ";
251 int indx = 0;
252 for (StructType::ElementTypes::const_iterator
253 I = STy->getElementTypes().begin(),
254 E = STy->getElementTypes().end(); I != E; ++I) {
Chris Lattner16c7bb22002-05-09 02:28:59 +0000255 Result += calcTypeNameVar(*I, TypeNames,
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000256 "field" + itostr(indx++), tempstr);
257 Result += ";\n ";
258 }
259 Result += " } ";
260 break;
261 }
262 case Type::PointerTyID:
263 Result = calcTypeName(cast<const PointerType>(Ty)->getElementType(),
Chris Lattner16c7bb22002-05-09 02:28:59 +0000264 TypeNames, MInfo);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000265 Result += "*";
266 break;
267 case Type::ArrayTyID: {
268 const ArrayType *ATy = cast<const ArrayType>(Ty);
269 int NumElements = ATy->getNumElements();
Chris Lattner16c7bb22002-05-09 02:28:59 +0000270 Result = calcTypeName(ATy->getElementType(), TypeNames, MInfo);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000271 Result += "*";
272 break;
273 }
274 default:
275 assert(0 && "Unhandled case in getTypeProps!");
276 Result = "<error>";
277 }
278
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000279 return Result;
280}
281
282// Internal function
283// Pass the Type* variable and and the variable name and this prints out the
284// variable declaration.
285// This is different from calcTypeName because if you need to declare an array
286// the size of the array would appear after the variable name itself
287// For eg. int a[10];
Chris Lattner16c7bb22002-05-09 02:28:59 +0000288static string calcTypeNameVar(const Type *Ty,
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000289 map<const Type *, string> &TypeNames,
290 string VariableName, string NameSoFar) {
291 if (Ty->isPrimitiveType())
292 switch (Ty->getPrimitiveID()) {
293 case Type::BoolTyID:
Chris Lattner16c7bb22002-05-09 02:28:59 +0000294 return "bool " + NameSoFar + VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000295 case Type::UByteTyID:
296 return "unsigned char " + NameSoFar + VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000297 case Type::SByteTyID:
298 return "signed char " + NameSoFar + VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000299 case Type::UShortTyID:
300 return "unsigned long long " + NameSoFar + VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000301 case Type::ULongTyID:
302 return "unsigned long long " + NameSoFar + VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000303 case Type::LongTyID:
304 return "signed long long " + NameSoFar + VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000305 case Type::UIntTyID:
Chris Lattner16c7bb22002-05-09 02:28:59 +0000306 return "unsigned " + NameSoFar + VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000307 default :
308 return Ty->getDescription() + " " + NameSoFar + VariableName;
309 }
310
311 // Check to see if the type is named.
312 map<const Type *, string>::iterator I = TypeNames.find(Ty);
313 if (I != TypeNames.end())
314 return I->second + " " + NameSoFar + VariableName;
315
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000316 string Result;
317 string tempstr = "";
318
319 switch (Ty->getPrimitiveID()) {
320 case Type::FunctionTyID: {
321 string MInfo = "";
322 const FunctionType *MTy = cast<const FunctionType>(Ty);
Chris Lattner16c7bb22002-05-09 02:28:59 +0000323 Result += calcTypeName(MTy->getReturnType(), TypeNames, MInfo);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000324 if (MInfo != "")
325 Result += ") " + MInfo;
326 Result += " " + NameSoFar + VariableName;
327 Result += " (";
328 for (FunctionType::ParamTypes::const_iterator
329 I = MTy->getParamTypes().begin(),
330 E = MTy->getParamTypes().end(); I != E; ++I) {
331 if (I != MTy->getParamTypes().begin())
332 Result += ", ";
333 MInfo = "";
Chris Lattner16c7bb22002-05-09 02:28:59 +0000334 Result += calcTypeName(*I, TypeNames, MInfo);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000335 if (MInfo != "")
336 Result += ") " + MInfo;
337 }
338 if (MTy->isVarArg()) {
339 if (!MTy->getParamTypes().empty())
340 Result += ", ";
341 Result += "...";
342 }
343 Result += ")";
344 break;
345 }
346 case Type::StructTyID: {
347 const StructType *STy = cast<const StructType>(Ty);
348 Result = " struct {\n ";
349 int indx = 0;
350 for (StructType::ElementTypes::const_iterator
351 I = STy->getElementTypes().begin(),
352 E = STy->getElementTypes().end(); I != E; ++I) {
Chris Lattner16c7bb22002-05-09 02:28:59 +0000353 Result += calcTypeNameVar(*I, TypeNames,
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000354 "field" + itostr(indx++), "");
355 Result += ";\n ";
356 }
357 Result += " }";
358 Result += " " + NameSoFar + VariableName;
359 break;
360 }
361
362 case Type::PointerTyID: {
363 Result = calcTypeNameVar(cast<const PointerType>(Ty)->getElementType(),
Chris Lattner16c7bb22002-05-09 02:28:59 +0000364 TypeNames, tempstr,
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000365 "(*" + NameSoFar + VariableName + ")");
366 break;
367 }
368
369 case Type::ArrayTyID: {
370 const ArrayType *ATy = cast<const ArrayType>(Ty);
371 int NumElements = ATy->getNumElements();
Chris Lattner16c7bb22002-05-09 02:28:59 +0000372 Result = calcTypeNameVar(ATy->getElementType(), TypeNames,
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000373 tempstr, NameSoFar + VariableName + "[" +
374 itostr(NumElements) + "]");
375 break;
376 }
377 default:
378 assert(0 && "Unhandled case in getTypeProps!");
379 Result = "<error>";
380 }
381
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000382 return Result;
383}
384
385// printTypeVarInt - The internal guts of printing out a type that has a
386// potentially named portion and the variable associated with the type.
387static ostream &printTypeVarInt(ostream &Out, const Type *Ty,
388 map<const Type *, string> &TypeNames,
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000389 const string &VariableName) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000390 // Primitive types always print out their description, regardless of whether
391 // they have been named or not.
392
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000393 if (Ty->isPrimitiveType())
394 switch (Ty->getPrimitiveID()) {
395 case Type::BoolTyID:
Chris Lattner16c7bb22002-05-09 02:28:59 +0000396 return Out << "bool " << VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000397 case Type::UByteTyID:
398 return Out << "unsigned char " << VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000399 case Type::SByteTyID:
400 return Out << "signed char " << VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000401 case Type::UShortTyID:
402 return Out << "unsigned long long " << VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000403 case Type::ULongTyID:
404 return Out << "unsigned long long " << VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000405 case Type::LongTyID:
406 return Out << "signed long long " << VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000407 case Type::UIntTyID:
Chris Lattner16c7bb22002-05-09 02:28:59 +0000408 return Out << "unsigned " << VariableName;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000409 default :
410 return Out << Ty->getDescription() << " " << VariableName;
411 }
412
413 // Check to see if the type is named.
414 map<const Type *, string>::iterator I = TypeNames.find(Ty);
415 if (I != TypeNames.end()) return Out << I->second << " " << VariableName;
416
417 // Otherwise we have a type that has not been named but is a derived type.
418 // Carefully recurse the type hierarchy to print out any contained symbolic
419 // names.
420 //
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000421 string TypeNameVar, tempstr = "";
Chris Lattner16c7bb22002-05-09 02:28:59 +0000422 TypeNameVar = calcTypeNameVar(Ty, TypeNames, VariableName, tempstr);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000423 return Out << TypeNameVar;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000424}
425
426// Internal guts of printing a type name
427static ostream &printTypeInt(ostream &Out, const Type *Ty,
428 map<const Type *, string> &TypeNames) {
429 // Primitive types always print out their description, regardless of whether
430 // they have been named or not.
431
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000432 if (Ty->isPrimitiveType())
433 switch (Ty->getPrimitiveID()) {
434 case Type::BoolTyID:
Chris Lattner16c7bb22002-05-09 02:28:59 +0000435 return Out << "bool";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000436 case Type::UByteTyID:
437 return Out << "unsigned char";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000438 case Type::SByteTyID:
439 return Out << "signed char";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000440 case Type::UShortTyID:
Chris Lattner16c7bb22002-05-09 02:28:59 +0000441 return Out << "unsigned short";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000442 case Type::ULongTyID:
443 return Out << "unsigned long long";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000444 case Type::LongTyID:
445 return Out << "signed long long";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000446 case Type::UIntTyID:
Chris Lattner16c7bb22002-05-09 02:28:59 +0000447 return Out << "unsigned";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000448 default :
449 return Out << Ty->getDescription();
450 }
451
452 // Check to see if the type is named.
453 map<const Type *, string>::iterator I = TypeNames.find(Ty);
454 if (I != TypeNames.end()) return Out << I->second;
455
456 // Otherwise we have a type that has not been named but is a derived type.
457 // Carefully recurse the type hierarchy to print out any contained symbolic
458 // names.
459 //
Chris Lattner16c7bb22002-05-09 02:28:59 +0000460 string MInfo;
461 string TypeName = calcTypeName(Ty, TypeNames, MInfo);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000462 // TypeNames.insert(std::make_pair(Ty, TypeName));
463 //Cache type name for later use
464 if (MInfo != "")
465 return Out << TypeName << ")" << MInfo;
466 else
467 return Out << TypeName;
468}
469
470namespace {
471
472 //Internal CWriter class mimics AssemblyWriter.
473 class CWriter {
474 ostream& Out;
475 SlotCalculator &Table;
476 const Module *TheModule;
477 map<const Type *, string> TypeNames;
478 public:
479 inline CWriter(ostream &o, SlotCalculator &Tab, const Module *M)
480 : Out(o), Table(Tab), TheModule(M) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000481 }
482
Chris Lattner16c7bb22002-05-09 02:28:59 +0000483 inline void write(const Module *M) { printModule(M); }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000484
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000485 ostream& printTypeVar(const Type *Ty, const string &VariableName) {
486 return printTypeVarInt(Out, Ty, TypeNames, VariableName);
487 }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000488
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000489
490
491 ostream& printType(const Type *Ty, ostream &Out);
492 void writeOperand(const Value *Operand, ostream &Out,bool PrintName = true);
493
494 string getValueName(const Value *V);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000495 private :
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000496
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000497 void printModule(const Module *M);
498 void printSymbolTable(const SymbolTable &ST);
499 void printConstant(const Constant *CPV);
500 void printGlobal(const GlobalVariable *GV);
Chris Lattner16c7bb22002-05-09 02:28:59 +0000501 void printFunctionSignature(const Function *F);
502 void printFunctionDecl(const Function *F); // Print just the forward decl
503 void printFunctionArgument(const Argument *FA);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000504
505 void printFunction(const Function *);
506
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000507 void outputBasicBlock(const BasicBlock *);
508 };
509 /* END class CWriter */
510
511
512 /* CLASS InstLocalVarsVisitor */
513 class InstLocalVarsVisitor : public InstVisitor<InstLocalVarsVisitor> {
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000514 CWriter& CW;
Chris Lattner16c7bb22002-05-09 02:28:59 +0000515 void handleTerminator(TerminatorInst *tI, int indx);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000516 public:
517 CLocalVars CLV;
518
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000519 InstLocalVarsVisitor(CWriter &cw) : CW(cw) {}
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000520
521 void visitInstruction(Instruction *I) {
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000522 if (I->getType() != Type::VoidTy) {
523 string tempostr = CW.getValueName(I);
524 CLV.addLocalVar(I->getType(), tempostr);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000525 }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000526 }
527
528 void visitBranchInst(BranchInst *I) {
Chris Lattner16c7bb22002-05-09 02:28:59 +0000529 handleTerminator(I, 0);
530 if (I->isConditional())
531 handleTerminator(I, 1);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000532 }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000533 };
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000534}
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000535
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000536void InstLocalVarsVisitor::handleTerminator(TerminatorInst *tI,int indx) {
537 BasicBlock *bb = tI->getSuccessor(indx);
538
539 BasicBlock::const_iterator insIt = bb->begin();
540 while (insIt != bb->end()) {
541 if (const PHINode *pI = dyn_cast<PHINode>(*insIt)) {
542 // Its a phinode!
543 // Calculate the incoming index for this
544 assert(pI->getBasicBlockIndex(tI->getParent()) != -1);
545
546 CLV.addLocalVar(pI->getType(), CW.getValueName(pI));
547 } else
548 break;
549 insIt++;
550 }
551}
552
553namespace {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000554 /* CLASS CInstPrintVisitor */
555
556 class CInstPrintVisitor: public InstVisitor<CInstPrintVisitor> {
557 CWriter& CW;
558 SlotCalculator& Table;
559 ostream &Out;
560 const Value *Operand;
561
562 void outputLValue(Instruction *);
563 void printPhiFromNextBlock(TerminatorInst *tI, int indx);
Chris Lattner44408262002-05-09 03:50:42 +0000564 void printIndexingExpr(MemAccessInst *MAI);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000565
566 public:
567 CInstPrintVisitor (CWriter &cw, SlotCalculator& table, ostream& o)
Chris Lattner44408262002-05-09 03:50:42 +0000568 : CW(cw), Table(table), Out(o) {}
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000569
570 void visitCastInst(CastInst *I);
571 void visitCallInst(CallInst *I);
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000572 void visitShiftInst(ShiftInst *I) { visitBinaryOperator(I); }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000573 void visitReturnInst(ReturnInst *I);
574 void visitBranchInst(BranchInst *I);
575 void visitSwitchInst(SwitchInst *I);
576 void visitInvokeInst(InvokeInst *I) ;
577 void visitMallocInst(MallocInst *I);
578 void visitAllocaInst(AllocaInst *I);
579 void visitFreeInst(FreeInst *I);
580 void visitLoadInst(LoadInst *I);
581 void visitStoreInst(StoreInst *I);
582 void visitGetElementPtrInst(GetElementPtrInst *I);
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000583 void visitPHINode(PHINode *I) {}
584
585 void visitNot(GenericUnaryInst *I);
586 void visitBinaryOperator(Instruction *I);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000587 };
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000588}
589
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000590void CInstPrintVisitor::outputLValue(Instruction *I) {
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000591 Out << " " << CW.getValueName(I) << " = ";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000592}
593
594void CInstPrintVisitor::printPhiFromNextBlock(TerminatorInst *tI, int indx) {
595 BasicBlock *bb = tI->getSuccessor(indx);
596 BasicBlock::const_iterator insIt = bb->begin();
597 while (insIt != bb->end()) {
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000598 if (PHINode *pI = dyn_cast<PHINode>(*insIt)) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000599 //Its a phinode!
600 //Calculate the incoming index for this
601 int incindex = pI->getBasicBlockIndex(tI->getParent());
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000602 if (incindex != -1) {
603 //now we have to do the printing
604 outputLValue(pI);
605 CW.writeOperand(pI->getIncomingValue(incindex), Out);
606 Out << ";\n";
607 }
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000608 }
609 else break;
610 insIt++;
611 }
612}
613
614// Implement all "other" instructions, except for PHINode
615void CInstPrintVisitor::visitCastInst(CastInst *I) {
616 outputLValue(I);
617 Operand = I->getNumOperands() ? I->getOperand(0) : 0;
618 Out << "(";
619 CW.printType(I->getType(), Out);
620 Out << ")";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000621 CW.writeOperand(Operand, Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000622 Out << ";\n";
623}
624
625void CInstPrintVisitor::visitCallInst(CallInst *I) {
Chris Lattnerf34ee812002-05-09 03:12:34 +0000626 if (I->getType() != Type::VoidTy)
627 outputLValue(I);
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000628 else
629 Out << " ";
Chris Lattnerf34ee812002-05-09 03:12:34 +0000630
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000631 Operand = I->getNumOperands() ? I->getOperand(0) : 0;
632 const PointerType *PTy = dyn_cast<PointerType>(Operand->getType());
633 const FunctionType *MTy = PTy
634 ? dyn_cast<FunctionType>(PTy->getElementType()):0;
635 const Type *RetTy = MTy ? MTy->getReturnType() : 0;
636
637 // If possible, print out the short form of the call instruction, but we can
638 // only do this if the first argument is a pointer to a nonvararg method,
639 // and if the value returned is not a pointer to a method.
640 //
641 if (RetTy && !MTy->isVarArg() &&
642 (!isa<PointerType>(RetTy)||
643 !isa<FunctionType>(cast<PointerType>(RetTy)))){
644 Out << " ";
645 Out << makeNameProper(Operand->getName());
646 } else {
647 Out << makeNameProper(Operand->getName());
648 }
649 Out << "(";
650 if (I->getNumOperands() > 1)
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000651 CW.writeOperand(I->getOperand(1), Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000652 for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
653 Out << ",";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000654 CW.writeOperand(I->getOperand(op), Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000655 }
656
657 Out << " );\n";
658}
659
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000660// Specific Instruction type classes... note that all of the casts are
661// neccesary because we use the instruction classes as opaque types...
662//
663void CInstPrintVisitor::visitReturnInst(ReturnInst *I) {
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000664 Out << " return ";
Chris Lattner16c7bb22002-05-09 02:28:59 +0000665 if (I->getNumOperands())
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000666 CW.writeOperand(I->getOperand(0), Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000667 Out << ";\n";
668}
669
670void CInstPrintVisitor::visitBranchInst(BranchInst *I) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000671 TerminatorInst *tI = cast<TerminatorInst>(I);
Chris Lattner16c7bb22002-05-09 02:28:59 +0000672 if (I->isConditional()) {
673 Out << " if (";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000674 CW.writeOperand(I->getCondition(), Out);
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000675 Out << ") {\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000676 printPhiFromNextBlock(tI,0);
Chris Lattner16c7bb22002-05-09 02:28:59 +0000677 Out << " goto ";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000678 CW.writeOperand(I->getOperand(0), Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000679 Out << ";\n";
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000680 Out << " } else {\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000681 printPhiFromNextBlock(tI,1);
Chris Lattner16c7bb22002-05-09 02:28:59 +0000682 Out << " goto ";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000683 CW.writeOperand(I->getOperand(1), Out);
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000684 Out << ";\n }\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000685 } else {
686 printPhiFromNextBlock(tI,0);
687 Out << " goto ";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000688 CW.writeOperand(I->getOperand(0), Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000689 Out << ";\n";
690 }
691 Out << "\n";
692}
693
694void CInstPrintVisitor::visitSwitchInst(SwitchInst *I) {
Chris Lattnerf34ee812002-05-09 03:12:34 +0000695 assert(0 && "Switch not implemented!");
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000696}
697
698void CInstPrintVisitor::visitInvokeInst(InvokeInst *I) {
Chris Lattnerf34ee812002-05-09 03:12:34 +0000699 assert(0 && "Invoke not implemented!");
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000700}
701
702void CInstPrintVisitor::visitMallocInst(MallocInst *I) {
703 outputLValue(I);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000704 Out << "(";
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000705 CW.printType(I->getType()->getElementType(), Out);
706 Out << "*)malloc(sizeof(";
707 CW.printTypeVar(I->getType()->getElementType(), "");
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000708 Out << ")";
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000709
710 if (I->isArrayAllocation()) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000711 Out << " * " ;
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000712 CW.writeOperand(I->getOperand(0), Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000713 }
714 Out << ");";
715}
716
717void CInstPrintVisitor::visitAllocaInst(AllocaInst *I) {
718 outputLValue(I);
719 Operand = I->getNumOperands() ? I->getOperand(0) : 0;
720 string tempstr = "";
721 Out << "(";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000722 CW.printTypeVar(I->getType(), tempstr);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000723 Out << ") alloca(sizeof(";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000724 CW.printTypeVar(cast<PointerType>(I->getType())->getElementType(),
725 tempstr);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000726 Out << ")";
727 if (I->getNumOperands()) {
728 Out << " * " ;
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000729 CW.writeOperand(Operand, Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000730 }
731 Out << ");\n";
732}
733
734void CInstPrintVisitor::visitFreeInst(FreeInst *I) {
735 Operand = I->getNumOperands() ? I->getOperand(0) : 0;
736 Out << "free(";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000737 CW.writeOperand(Operand, Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000738 Out << ");\n";
739}
740
Chris Lattner44408262002-05-09 03:50:42 +0000741void CInstPrintVisitor::printIndexingExpr(MemAccessInst *MAI) {
742 CW.writeOperand(MAI->getPointerOperand(), Out);
743
744 for (MemAccessInst::op_iterator I = MAI->idx_begin(), E = MAI->idx_end();
745 I != E; ++I)
746 if ((*I)->getType() == Type::UIntTy) {
747 Out << "[";
748 CW.writeOperand(*I, Out);
749 Out << "]";
750 } else {
751 Out << ".field" << cast<ConstantUInt>(*I)->getValue();
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000752 }
Chris Lattner44408262002-05-09 03:50:42 +0000753}
754
755void CInstPrintVisitor::visitLoadInst(LoadInst *I) {
756 outputLValue(I);
757 printIndexingExpr(I);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000758 Out << ";\n";
759}
760
Chris Lattner44408262002-05-09 03:50:42 +0000761void CInstPrintVisitor::visitStoreInst(StoreInst *I) {
762 Out << " ";
763 printIndexingExpr(I);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000764 Out << " = ";
Chris Lattner44408262002-05-09 03:50:42 +0000765 CW.writeOperand(I->getOperand(0), Out);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000766 Out << ";\n";
767}
768
769void CInstPrintVisitor::visitGetElementPtrInst(GetElementPtrInst *I) {
770 outputLValue(I);
Chris Lattner44408262002-05-09 03:50:42 +0000771 Out << "&";
772 printIndexingExpr(I);
773 Out << ";\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000774}
775
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000776void CInstPrintVisitor::visitNot(GenericUnaryInst *I) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000777 outputLValue(I);
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000778 Out << "~";
779 CW.writeOperand(I->getOperand(0), Out);
780 Out << ";\n";
781}
782
783void CInstPrintVisitor::visitBinaryOperator(Instruction *I) {
784 // binary instructions, shift instructions, setCond instructions.
785 outputLValue(I);
786 if (isa<PointerType>(I->getType())) {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000787 Out << "(";
788 CW.printType(I->getType(), Out);
789 Out << ")";
790 }
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000791
792 if (isa<PointerType>(I->getType())) Out << "(long long)";
793 CW.writeOperand(I->getOperand(0), Out);
794
795 switch (I->getOpcode()) {
796 case Instruction::Add: Out << "+"; break;
797 case Instruction::Sub: Out << "-"; break;
798 case Instruction::Mul: Out << "*"; break;
799 case Instruction::Div: Out << "/"; break;
800 case Instruction::Rem: Out << "%"; break;
801 case Instruction::And: Out << "&"; break;
802 case Instruction::Or: Out << "|"; break;
803 case Instruction::Xor: Out << "^"; break;
804 case Instruction::SetEQ: Out << "=="; break;
805 case Instruction::SetNE: Out << "!="; break;
806 case Instruction::SetLE: Out << "<="; break;
807 case Instruction::SetGE: Out << ">="; break;
808 case Instruction::SetLT: Out << "<"; break;
809 case Instruction::SetGT: Out << ">"; break;
810 case Instruction::Shl : Out << "<<"; break;
811 case Instruction::Shr : Out << ">>"; break;
812 default: cerr << "Invalid operator type!" << I; abort();
813 }
814
815 if (isa<PointerType>(I->getType())) Out << "(long long)";
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000816 CW.writeOperand(I->getOperand(1), Out);
Chris Lattner2f5f51a2002-05-09 03:28:37 +0000817 Out << ";\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000818}
819
820/* END : CInstPrintVisitor implementation */
821
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000822string CWriter::getValueName(const Value *V) {
823 if (V->hasName()) // Print out the label if it exists...
Chris Lattner44408262002-05-09 03:50:42 +0000824 return "l_" + makeNameProper(V->getName()) + "_" +
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000825 utostr(V->getType()->getUniqueID());
826
827 int Slot = Table.getValSlot(V);
828 assert(Slot >= 0 && "Invalid value!");
Chris Lattner44408262002-05-09 03:50:42 +0000829 return "ltmp_" + itostr(Slot) + "_" +
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000830 utostr(V->getType()->getUniqueID());
831}
832
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000833void CWriter::printModule(const Module *M) {
834 // printing stdlib inclusion
835 // Out << "#include <stdlib.h>\n";
836
Chris Lattner16c7bb22002-05-09 02:28:59 +0000837 // get declaration for alloca
838 Out << "/* Provide Declarations */\n"
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000839 << "#include <alloca.h>\n\n"
Chris Lattner16c7bb22002-05-09 02:28:59 +0000840
841 // Provide a definition for null if one does not already exist.
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000842 << "#ifndef NULL\n#define NULL 0\n#endif\n\n"
Chris Lattner16c7bb22002-05-09 02:28:59 +0000843 << "typedef unsigned char bool;\n"
844
845 << "\n\n/* Global Symbols */\n";
846
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000847 // Loop over the symbol table, emitting all named constants...
848 if (M->hasSymbolTable())
849 printSymbolTable(*M->getSymbolTable());
850
Chris Lattner16c7bb22002-05-09 02:28:59 +0000851 Out << "\n\n/* Global Data */\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000852 for_each(M->gbegin(), M->gend(),
853 bind_obj(this, &CWriter::printGlobal));
854
Chris Lattner16c7bb22002-05-09 02:28:59 +0000855 // First output all the declarations of the functions as C requires Functions
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000856 // be declared before they are used.
Chris Lattner16c7bb22002-05-09 02:28:59 +0000857 //
858 Out << "\n\n/* Function Declarations */\n";
859 for_each(M->begin(), M->end(), bind_obj(this, &CWriter::printFunctionDecl));
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000860
Chris Lattner16c7bb22002-05-09 02:28:59 +0000861 // Output all of the functions...
862 Out << "\n\n/* Function Bodies */\n";
863 for_each(M->begin(), M->end(), bind_obj(this, &CWriter::printFunction));
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000864}
865
866// prints the global constants
867void CWriter::printGlobal(const GlobalVariable *GV) {
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000868 string tempostr = getValueName(GV);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000869 if (GV->hasInternalLinkage()) Out << "static ";
870
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000871 printTypeVar(GV->getType()->getElementType(), tempostr);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000872
873 if (GV->hasInitializer()) {
874 Out << " = " ;
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000875 writeOperand(GV->getInitializer(), Out, false);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000876 }
877
878 Out << ";\n";
879}
880
881// printSymbolTable - Run through symbol table looking for named constants
882// if a named constant is found, emit it's declaration...
883// Assuming that symbol table has only types and constants.
884void CWriter::printSymbolTable(const SymbolTable &ST) {
885 // GraphT G;
886 for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
887 SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
888 SymbolTable::type_const_iterator End = ST.type_end(TI->first);
889
890 // TODO
891 // Need to run through all the used types in the program
892 // FindUsedTypes &FUT = new FindUsedTypes();
893 // const std::set<const Type *> &UsedTypes = FUT.getTypes();
894 // Filter out the structures printing forward definitions for each of them
895 // and creating the dependency graph.
896 // Print forward definitions to all of them
897 // print the typedefs topologically sorted
898
899 // But for now we have
900 for (; I != End; ++I) {
901 const Value *V = I->second;
902 if (const Constant *CPV = dyn_cast<const Constant>(V)) {
903 printConstant(CPV);
904 } else if (const Type *Ty = dyn_cast<const Type>(V)) {
905 string tempostr;
906 string tempstr = "";
907 Out << "typedef ";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000908 tempostr = "llvm__" + I->first;
Chris Lattner16c7bb22002-05-09 02:28:59 +0000909 string TypeNameVar = calcTypeNameVar(Ty, TypeNames,
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000910 tempostr, tempstr);
911 Out << TypeNameVar << ";\n";
912 if (!isa<PointerType>(Ty) ||
913 !cast<PointerType>(Ty)->getElementType()->isPrimitiveType())
914 TypeNames.insert(std::make_pair(Ty, "llvm__"+I->first));
915 }
916 }
917 }
918}
919
920
921// printConstant - Print out a constant pool entry...
922//
923void CWriter::printConstant(const Constant *CPV) {
924 // TODO
925 // Dinakar : Don't know what to do with unnamed constants
926 // should do something about it later.
927
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000928 string tempostr = getValueName(CPV);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000929
930 // Print out the constant type...
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000931 printTypeVar(CPV->getType(), tempostr);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000932
933 Out << " = ";
934 // Write the value out now...
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000935 writeOperand(CPV, Out, false);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000936
937 Out << "\n";
938}
939
Chris Lattner16c7bb22002-05-09 02:28:59 +0000940// printFunctionDecl - Print function declaration
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000941//
Chris Lattner16c7bb22002-05-09 02:28:59 +0000942void CWriter::printFunctionDecl(const Function *F) {
943 printFunctionSignature(F);
944 Out << ";\n";
945}
946
947void CWriter::printFunctionSignature(const Function *F) {
948 if (F->hasInternalLinkage()) Out << "static ";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000949
950 // Loop over the arguments, printing them...
Chris Lattner16c7bb22002-05-09 02:28:59 +0000951 const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000952
Chris Lattner16c7bb22002-05-09 02:28:59 +0000953 // Print out the return type and name...
954 printType(F->getReturnType(), Out);
955 Out << " " << makeNameProper(F->getName()) << "(";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000956
Chris Lattner16c7bb22002-05-09 02:28:59 +0000957 if (!F->isExternal()) {
958 for_each(F->getArgumentList().begin(), F->getArgumentList().end(),
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000959 bind_obj(this, &CWriter::printFunctionArgument));
960 } else {
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000961 // Loop over the arguments, printing them...
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000962 for (FunctionType::ParamTypes::const_iterator I =
Chris Lattner16c7bb22002-05-09 02:28:59 +0000963 FT->getParamTypes().begin(),
964 E = FT->getParamTypes().end(); I != E; ++I) {
965 if (I != FT->getParamTypes().begin()) Out << ", ";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000966 printType(*I, Out);
967 }
968 }
969
970 // Finish printing arguments...
Chris Lattner16c7bb22002-05-09 02:28:59 +0000971 if (FT->isVarArg()) {
972 if (FT->getParamTypes().size()) Out << ", ";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000973 Out << "..."; // Output varargs portion of signature!
974 }
Chris Lattner16c7bb22002-05-09 02:28:59 +0000975 Out << ")";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000976}
977
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000978
979// printFunctionArgument - This member is called for every argument that
980// is passed into the method. Simply print it out
981//
982void CWriter::printFunctionArgument(const Argument *Arg) {
983 // Insert commas as we go... the first arg doesn't get a comma
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000984 if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
985
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000986 // Output type...
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000987 printTypeVar(Arg->getType(), getValueName(Arg));
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000988}
989
Chris Lattner16c7bb22002-05-09 02:28:59 +0000990void CWriter::printFunction(const Function *F) {
991 if (F->isExternal()) return;
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +0000992
Chris Lattnerf34ee812002-05-09 03:12:34 +0000993 Table.incorporateFunction(F);
994
Chris Lattner16c7bb22002-05-09 02:28:59 +0000995 // Process each of the basic blocks, gather information and call the
996 // output methods on the CLocalVars and Function* objects.
997
998 // gather local variable information for each basic block
Chris Lattnerb5af06a2002-05-09 03:06:06 +0000999 InstLocalVarsVisitor ILV(*this);
Chris Lattner16c7bb22002-05-09 02:28:59 +00001000 ILV.visit((Function *)F);
1001
1002 printFunctionSignature(F);
1003 Out << " {\n";
1004
1005 // Loop over the symbol table, emitting all named constants...
1006 if (F->hasSymbolTable())
1007 printSymbolTable(*F->getSymbolTable());
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001008
Chris Lattner16c7bb22002-05-09 02:28:59 +00001009 // print the local variables
1010 // we assume that every local variable is alloca'ed in the C code.
1011 std::map<const Type*, VarListType> &locals = ILV.CLV.LocalVars;
1012
1013 map<const Type*, VarListType>::iterator iter;
1014 for (iter = locals.begin(); iter != locals.end(); ++iter) {
1015 VarListType::iterator listiter;
1016 for (listiter = iter->second.begin(); listiter != iter->second.end();
1017 ++listiter) {
1018 Out << " ";
Chris Lattnerb5af06a2002-05-09 03:06:06 +00001019 printTypeVar(iter->first, *listiter);
Chris Lattner16c7bb22002-05-09 02:28:59 +00001020 Out << ";\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001021 }
1022 }
Chris Lattner16c7bb22002-05-09 02:28:59 +00001023
1024 // print the basic blocks
1025 for_each(F->begin(), F->end(), bind_obj(this, &CWriter::outputBasicBlock));
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001026
Chris Lattner16c7bb22002-05-09 02:28:59 +00001027 Out << "}\n";
Chris Lattnerf34ee812002-05-09 03:12:34 +00001028 Table.purgeFunction();
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001029}
1030
1031void CWriter::outputBasicBlock(const BasicBlock* BB) {
Chris Lattnerb5af06a2002-05-09 03:06:06 +00001032 Out << getValueName(BB) << ":\n";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001033
1034 // Output all of the instructions in the basic block...
1035 // print the basic blocks
1036 CInstPrintVisitor CIPV(*this, Table, Out);
1037 CIPV.visit((BasicBlock *) BB);
1038}
1039
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001040// printType - Go to extreme measures to attempt to print out a short, symbolic
1041// version of a type name.
1042ostream& CWriter::printType(const Type *Ty, ostream &Out) {
1043 return printTypeInt(Out, Ty, TypeNames);
1044}
1045
1046
Chris Lattnerb5af06a2002-05-09 03:06:06 +00001047void CWriter::writeOperand(const Value *Operand,
Chris Lattner16c7bb22002-05-09 02:28:59 +00001048 ostream &Out, bool PrintName = true) {
Chris Lattner44408262002-05-09 03:50:42 +00001049 if (isa<GlobalValue>(Operand))
1050 Out << "(&"; // Global values are references as their addresses by llvm
1051
Chris Lattner16c7bb22002-05-09 02:28:59 +00001052 if (PrintName && Operand->hasName()) {
1053 // If Operand has a name.
Chris Lattner44408262002-05-09 03:50:42 +00001054 Out << "l_" << makeNameProper(Operand->getName()) << "_" <<
Chris Lattner16c7bb22002-05-09 02:28:59 +00001055 Operand->getType()->getUniqueID();
Chris Lattner44408262002-05-09 03:50:42 +00001056 } else if (const Constant *CPV = dyn_cast<const Constant>(Operand)) {
Chris Lattner16c7bb22002-05-09 02:28:59 +00001057 if (isa<ConstantPointerNull>(CPV))
1058 Out << "NULL";
1059 else
1060 Out << getConstStrValue(CPV);
Chris Lattner44408262002-05-09 03:50:42 +00001061 } else {
Chris Lattner16c7bb22002-05-09 02:28:59 +00001062 int Slot = Table.getValSlot(Operand);
1063 if (Slot >= 0)
Chris Lattner44408262002-05-09 03:50:42 +00001064 Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
Chris Lattner16c7bb22002-05-09 02:28:59 +00001065 else if (PrintName)
1066 Out << "<badref>";
1067 }
Chris Lattner44408262002-05-09 03:50:42 +00001068
1069 if (isa<GlobalValue>(Operand))
1070 Out << ")";
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001071}
1072
1073
1074//===----------------------------------------------------------------------===//
1075// External Interface declaration
1076//===----------------------------------------------------------------------===//
1077
Chris Lattnerf34ee812002-05-09 03:12:34 +00001078void WriteToC(const Module *M, ostream &Out) {
1079 assert(M && "You can't write a null module!!");
1080 SlotCalculator SlotTable(M, false);
1081 CWriter W(Out, SlotTable, M);
1082 W.write(M);
Sumant Kowshik9ddc86c2002-05-08 18:09:58 +00001083 Out.flush();
1084}