1 using System;
2 using System.Collections;
3 using CodeFormatter = System.Text.CodeFormatter;
4
5 namespace cmsx.intermediate
6 {
7 public class Context
8 {
9 public nothrow Context() : compileUnit(*this), currentFunction(null), currentBasicBlock(null)
10 {
11 }
12 public inline nothrow TypeRepository& GetTypeRepository()
13 {
14 return typeRepository;
15 }
16 public inline nothrow Function* CurrentFunction() const
17 {
18 return currentFunction;
19 }
20 public inline nothrow void SetCurrentFunction(Function* currentFunction_)
21 {
22 currentFunction = currentFunction_;
23 }
24 public inline nothrow BasicBlock* CurrentBasicBlock() const
25 {
26 return currentBasicBlock;
27 }
28 public inline nothrow void SetCurrentBasicBlock(BasicBlock* basicBlock)
29 {
30 currentBasicBlock = basicBlock;
31 }
32 public inline nothrow Type* GetVoidType() const
33 {
34 return typeRepository.GetVoidType();
35 }
36 public inline nothrow BoolType* GetBoolType() const
37 {
38 return typeRepository.GetBoolType();
39 }
40 public inline nothrow SByteType* GetSByteType() const
41 {
42 return typeRepository.GetSByteType();
43 }
44 public inline nothrow ByteType* GetByteType() const
45 {
46 return typeRepository.GetByteType();
47 }
48 public inline nothrow ShortType* GetShortType() const
49 {
50 return typeRepository.GetShortType();
51 }
52 public inline nothrow UShortType* GetUShortType() const
53 {
54 return typeRepository.GetUShortType();
55 }
56 public inline nothrow IntType* GetIntType() const
57 {
58 return typeRepository.GetIntType();
59 }
60 public inline nothrow UIntType* GetUIntType() const
61 {
62 return typeRepository.GetUIntType();
63 }
64 public inline nothrow LongType* GetLongType() const
65 {
66 return typeRepository.GetLongType();
67 }
68 public inline nothrow ULongType* GetULongType() const
69 {
70 return typeRepository.GetULongType();
71 }
72 public inline nothrow FloatType* GetFloatType() const
73 {
74 return typeRepository.GetFloatType();
75 }
76 public inline nothrow DoubleType* GetDoubleType() const
77 {
78 return typeRepository.GetDoubleType();
79 }
80 public void AddPtrType(const string& typeId, int line)
81 {
82 typeRepository.AddPtrType(typeId, line);
83 }
84 public void AddStructureType(const string& typeId, const List<string>& memberTypeIds)
85 {
86 typeRepository.AddStructureType(typeId, memberTypeIds);
87 }
88 public void AddArrayType(const string& typeId, const string& elementTypeId, long size)
89 {
90 typeRepository.AddArrayType(typeId, elementTypeId, size);
91 }
92 public void AddFunctionType(const string& typeId, const string& returnTypeId, const List<string>& paramTypeIds)
93 {
94 typeRepository.AddFunctionType(typeId, returnTypeId, paramTypeIds);
95 }
96 public void ResolveTypes()
97 {
98 typeRepository.ResolveTypes();
99 }
100 public nothrow void SetFileName(const string& fileName)
101 {
102 compileUnit.SetFileName(fileName);
103 }
104 public Function* AddFunction(int lineNumber, Type* type, const string& name, bool once, MDStructRef* md)
105 {
106 return compileUnit.AddFunction(lineNumber, type, name, once, md);
107 }
108 public Type* GetTypeById(int lineNumber, const string& typeId) const
109 {
110 Type* type = typeRepository.GetTypeById(typeId);
111 if (type != null)
112 {
113 return type;
114 }
115 else
116 {
117 throw Exception("type for id '" + typeId + "' not found (" + compileUnit.fileName + ":" + ToString(lineNumber) + ")");
118 }
119 }
120 public PtrType* GetPtrType(Type* baseType)
121 {
122 return typeRepository.GetPtrType(baseType);
123 }
124 public ConstantValue* MakeSymbolValue(int lineNumber, const string& symbol, Type* type)
125 {
126 HashMap<string, SymbolValue*>.ConstIterator it = symbolValueMap.CFind(symbol);
127 if (it != symbolValueMap.CEnd())
128 {
129 SymbolValue* symbolValue = it->second;
130 if (symbolValue->type != type)
131 {
132 throw Exception("type " + type->Name() + " conflicts type " + symbolValue->type->Name() + " in earlier definition at line " + ToString(symbolValue->line) +
133 " (" + compileUnit.fileName + ":" + ToString(lineNumber) + ")");
134 }
135 return symbolValue;
136 }
137 else
138 {
139 SymbolValue* symbolValue = new SymbolValue(symbol);
140 symbolValue->type = type;
141 symbolValue->line = lineNumber;
142 values.Add(UniquePtr<Value>(symbolValue));
143 symbolValueMap[symbol] = symbolValue;
144 return symbolValue;
145 }
146 }
147 public ConstantValue* MakeLiteralValue(int lineNumber, const string& fromStr, Type* type)
148 {
149 try
150 {
151 ConstantValue* value = type->MakeValue(fromStr, *this);
152 if (value->type == null)
153 {
154 value->type = type;
155 }
156 return value;
157 }
158 catch (const Exception& ex)
159 {
160 throw Exception(ex.Message() + " (" + compileUnit.fileName + ":" + ToString(lineNumber) + ")");
161 }
162 return null;
163 }
164 public ConstantValue* MakeSByteValue(SByteType* type, sbyte value)
165 {
166 HashMap<sbyte, ConstantValue*>.ConstIterator it = sbyteValueMap.CFind(value);
167 if (it != sbyteValueMap.CEnd())
168 {
169 return it->second;
170 }
171 else
172 {
173 SByteValue* val = new SByteValue(value);
174 val->type = type;
175 AddValue(val);
176 sbyteValueMap[value] = val;
177 return val;
178 }
179 }
180 public ConstantValue* MakeByteValue(ByteType* type, byte value)
181 {
182 HashMap<byte, ConstantValue*>.ConstIterator it = byteValueMap.CFind(value);
183 if (it != byteValueMap.CEnd())
184 {
185 return it->second;
186 }
187 else
188 {
189 ByteValue* val = new ByteValue(value);
190 val->type = type;
191 AddValue(val);
192 byteValueMap[value] = val;
193 return val;
194 }
195 }
196 public ConstantValue* MakeShortValue(ShortType* type, short value)
197 {
198 HashMap<short, ConstantValue*>.ConstIterator it = shortValueMap.CFind(value);
199 if (it != shortValueMap.CEnd())
200 {
201 return it->second;
202 }
203 else
204 {
205 ShortValue* val = new ShortValue(value);
206 val->type = type;
207 AddValue(val);
208 shortValueMap[value] = val;
209 return val;
210 }
211 }
212 public ConstantValue* MakeUShortValue(UShortType* type, ushort value)
213 {
214 HashMap<ushort, ConstantValue*>.ConstIterator it = ushortValueMap.CFind(value);
215 if (it != ushortValueMap.CEnd())
216 {
217 return it->second;
218 }
219 else
220 {
221 UShortValue* val = new UShortValue(value);
222 val->type = type;
223 AddValue(val);
224 ushortValueMap[value] = val;
225 return val;
226 }
227 }
228 public ConstantValue* MakeIntValue(IntType* type, int value)
229 {
230 HashMap<int, ConstantValue*>.ConstIterator it = intValueMap.CFind(value);
231 if (it != intValueMap.CEnd())
232 {
233 return it->second;
234 }
235 else
236 {
237 IntValue* val = new IntValue(value);
238 val->type = type;
239 AddValue(val);
240 intValueMap[value] = val;
241 return val;
242 }
243 }
244 public ConstantValue* MakeUIntValue(UIntType* type, uint value)
245 {
246 HashMap<uint, ConstantValue*>.ConstIterator it = uintValueMap.CFind(value);
247 if (it != uintValueMap.CEnd())
248 {
249 return it->second;
250 }
251 else
252 {
253 UIntValue* val = new UIntValue(value);
254 val->type = type;
255 AddValue(val);
256 uintValueMap[value] = val;
257 return val;
258 }
259 }
260 public ConstantValue* MakeLongValue(LongType* type, long value)
261 {
262 HashMap<long, ConstantValue*>.ConstIterator it = longValueMap.CFind(value);
263 if (it != longValueMap.CEnd())
264 {
265 return it->second;
266 }
267 else
268 {
269 LongValue* val = new LongValue(value);
270 val->type = type;
271 AddValue(val);
272 longValueMap[value] = val;
273 return val;
274 }
275 }
276 public ConstantValue* MakeULongValue(ULongType* type, ulong value)
277 {
278 HashMap<ulong, ConstantValue*>.ConstIterator it = ulongValueMap.CFind(value);
279 if (it != ulongValueMap.CEnd())
280 {
281 return it->second;
282 }
283 else
284 {
285 ULongValue* val = new ULongValue(value);
286 val->type = type;
287 AddValue(val);
288 ulongValueMap[value] = val;
289 return val;
290 }
291 }
292 public ConstantValue* MakeFloatValue(FloatType* type, float value)
293 {
294 FloatValue* val = new FloatValue(value);
295 val->type = type;
296 AddValue(val);
297 return val;
298 }
299 public ConstantValue* MakeDoubleValue(DoubleType* type, double value)
300 {
301 DoubleValue* val = new DoubleValue(value);
302 val->type = type;
303 AddValue(val);
304 return val;
305 }
306 public ArrayValue* MakeArrayValue()
307 {
308 ArrayValue* val = new ArrayValue();
309 AddValue(val);
310 return val;
311 }
312 public StructureValue* MakeStructureValue()
313 {
314 StructureValue* val = new StructureValue();
315 AddValue(val);
316 return val;
317 }
318 public StringValue* MakeStringValue(const string& value)
319 {
320 #assert(value.StartsWith("\"") && value.EndsWith("\""));
321 StringValue* val = new StringValue(value.Substring(1, value.Length() - 2));
322 val->type = GetByteType();
323 AddValue(val);
324 return val;
325 }
326 public StringArrayValue* MakeStringArrayValue(char prefix)
327 {
328 StringArrayValue* val = new StringArrayValue(prefix);
329 bool error = false;
330 switch (prefix)
331 {
332 case 'w': val->type = GetUShortType(); break;
333 case 'u': val->type = GetUIntType(); break;
334 case 'b': val->type = GetByteType(); break;
335 default: error = true; break;
336 }
337 if (error)
338 {
339 throw Exception("invalid prefix '" + ToString(prefix) + "'");
340 }
341 AddValue(val);
342 return val;
343 }
344 public ConversionValue* MakeConversionValue(Type* targetType, ConstantValue* from, int lineNumber)
345 {
346 ConversionValue* val = new ConversionValue(targetType, from);
347 val->type = targetType;
348 val->line = lineNumber;
349 AddValue(val);
350 return val;
351 }
352 public void PrintTypes(CodeFormatter& formatter)
353 {
354 typeRepository.PrintTypes(formatter);
355 }
356 public void AddValue(Value* value)
357 {
358 values.Add(UniquePtr<Value>(value));
359 }
360 public nothrow LiteralOperand* GetLiteralOperand(ulong value)
361 {
362 HashMap<ulong, LiteralOperand*>.ConstIterator it = literalOperandMap.CFind(value);
363 if (it != literalOperandMap.CEnd())
364 {
365 return it->second;
366 }
367 else
368 {
369 LiteralOperand* literalOperand = new LiteralOperand(value);
370 operands.Add(UniquePtr<Operand>(literalOperand));
371 literalOperandMap[value] = literalOperand;
372 return literalOperand;
373 }
374 }
375 public nothrow LiteralOperand* CreateLiteralOperand()
376 {
377 LiteralOperand* literalOperand = new LiteralOperand();
378 operands.Add(UniquePtr<Operand>(literalOperand));
379 return literalOperand;
380 }
381 public nothrow SymbolOperand* GetSymbolOperand(const string& value)
382 {
383 HashMap<string, SymbolOperand*>.ConstIterator it = symbolOperandMap.CFind(value);
384 if (it != symbolOperandMap.CEnd())
385 {
386 return it->second;
387 }
388 else
389 {
390 SymbolOperand* symbolOperand = new SymbolOperand(value);
391 operands.Add(UniquePtr<Operand>(symbolOperand));
392 symbolOperandMap[value] = symbolOperand;
393 return symbolOperand;
394 }
395 }
396 public nothrow Operand* GetStringOperand(const string& value)
397 {
398 StringOperand* stringOperand = new StringOperand(value);
399 operands.Add(UniquePtr<Operand>(stringOperand));
400 return stringOperand;
401 }
402 public nothrow Operand* GetClsIdOperand(const string& typeId)
403 {
404 ClsIdOperand* clsIdOperand = new ClsIdOperand(typeId);
405 operands.Add(UniquePtr<Operand>(clsIdOperand));
406 return clsIdOperand;
407 }
408 public GlobalVariable* GetGlobalVariableNothrow(const string& globalVariableName) const
409 {
410 return compileUnit.GetGlobalVariableNothrow(globalVariableName);
411 }
412 public GlobalVariable* GetGlobalVariable(const string& globalVariableName) const
413 {
414 return compileUnit.GetGlobalVariable(globalVariableName);
415 }
416 public void AddGlobalVariable(Type* type, const string& name, ConstantValue* initializer, int line, bool once)
417 {
418 compileUnit.AddGlobalVariable(type, name, initializer, line, once);
419 }
420 public void ValidateGlobalVariables()
421 {
422 compileUnit.ValidateGlobalVariables();
423 }
424 public ClsIdValue* MakeClsIdValue(Type* type, const string& clsIdStr, int line)
425 {
426 #assert(clsIdStr.StartsWith("clsid(") && clsIdStr.EndsWith(")"));
427 string typeId = clsIdStr.Substring(6, clsIdStr.Length() - 6 - 1);
428 ClsIdValue* val = new ClsIdValue(typeId);
429 val->type = type;
430 val->line = line;
431 AddValue(val);
432 return val;
433 }
434 public void SetCompileUnitInfo(const string& compileUnitId, MDStructRef* mdRef)
435 {
436 compileUnit.AddInfo(compileUnitId, mdRef);
437 }
438 public MDBool* CreateMDBool(bool value)
439 {
440 return compileUnit.metadata.CreateMDBool(value);
441 }
442 public MDLong* CreateMDLong(long value)
443 {
444 return compileUnit.metadata.CreateMDLong(value);
445 }
446 public MDString* CreateMDString(const string& value)
447 {
448 #assert(value.StartsWith("\"") && value.EndsWith("\""));
449 return compileUnit.metadata.CreateMDString(value.Substring(1, value.Length() - 2));
450 }
451 public MDStructRef* CreateMDStructRef(int id)
452 {
453 return compileUnit.metadata.CreateMDStructRef(id);
454 }
455 public MDStruct* CreateMDStruct(int id)
456 {
457 return compileUnit.metadata.CreateMDStruct(id);
458 }
459 public CompileUnit compileUnit;
460 public Function* currentFunction;
461 public Registers regs;
462 private TypeRepository typeRepository;
463 private BasicBlock* currentBasicBlock;
464 private List<UniquePtr<Value>> values;
465 private HashMap<uint, IdValue*> idValueMap;
466 private HashMap<string, SymbolValue*> symbolValueMap;
467 private HashMap<sbyte, ConstantValue*> sbyteValueMap;
468 private HashMap<byte, ConstantValue*> byteValueMap;
469 private HashMap<short, ConstantValue*> shortValueMap;
470 private HashMap<ushort, ConstantValue*> ushortValueMap;
471 private HashMap<int, ConstantValue*> intValueMap;
472 private HashMap<uint, ConstantValue*> uintValueMap;
473 private HashMap<long, ConstantValue*> longValueMap;
474 private HashMap<ulong, ConstantValue*> ulongValueMap;
475 private List<UniquePtr<Operand>> operands;
476 private HashMap<ulong, LiteralOperand*> literalOperandMap;
477 private HashMap<string, SymbolOperand*> symbolOperandMap;
478 }
479 }