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& typeIdint line)
 81         {
 82             typeRepository.AddPtrType(typeIdline);
 83         }
 84         public void AddStructureType(const string& typeIdconst List<string>& memberTypeIds)
 85         {
 86             typeRepository.AddStructureType(typeIdmemberTypeIds);
 87         }
 88         public void AddArrayType(const string& typeIdconst string& elementTypeIdlong size)
 89         {
 90             typeRepository.AddArrayType(typeIdelementTypeIdsize);
 91         }
 92         public void AddFunctionType(const string& typeIdconst string& returnTypeIdconst List<string>& paramTypeIds)
 93         {
 94             typeRepository.AddFunctionType(typeIdreturnTypeIdparamTypeIds);
 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 lineNumberType* typeconst string& namebool onceMDStructRef* md)
105         {
106             return compileUnit.AddFunction(lineNumbertypenameoncemd);
107         }
108         public Type* GetTypeById(int lineNumberconst 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 lineNumberconst string& symbolType* type)
125         {
126             HashMap<stringSymbolValue*>.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 lineNumberconst string& fromStrType* 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* typesbyte value)
165         {
166             HashMap<sbyteConstantValue*>.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* typebyte value)
181         {
182             HashMap<byteConstantValue*>.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* typeshort value)
197         {
198             HashMap<shortConstantValue*>.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* typeushort value)
213         {
214             HashMap<ushortConstantValue*>.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* typeint value)
229         {
230             HashMap<intConstantValue*>.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* typeuint value)
245         {
246             HashMap<uintConstantValue*>.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* typelong value)
261         {
262             HashMap<longConstantValue*>.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* typeulong value)
277         {
278             HashMap<ulongConstantValue*>.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* typefloat value)
293         {
294             FloatValue* val = new FloatValue(value);
295             val->type = type;
296             AddValue(val);
297             return val;
298         }
299         public ConstantValue* MakeDoubleValue(DoubleType* typedouble 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(1value.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* targetTypeConstantValue* fromint lineNumber)
345         {
346             ConversionValue* val = new ConversionValue(targetTypefrom);
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<ulongLiteralOperand*>.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<stringSymbolOperand*>.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* typeconst string& nameConstantValue* initializerint linebool once)
417         {
418             compileUnit.AddGlobalVariable(typenameinitializerlineonce);
419         }
420         public void ValidateGlobalVariables()
421         {
422             compileUnit.ValidateGlobalVariables();
423         }
424         public ClsIdValue* MakeClsIdValue(Type* typeconst string& clsIdStrint line)
425         {
426             #assert(clsIdStr.StartsWith("clsid(") && clsIdStr.EndsWith(")"));
427             string typeId = clsIdStr.Substring(6clsIdStr.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& compileUnitIdMDStructRef* mdRef)
435         {
436             compileUnit.AddInfo(compileUnitIdmdRef);
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(1value.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<uintIdValue*> idValueMap;
466         private HashMap<stringSymbolValue*> symbolValueMap;
467         private HashMap<sbyteConstantValue*> sbyteValueMap;
468         private HashMap<byteConstantValue*> byteValueMap;
469         private HashMap<shortConstantValue*> shortValueMap;
470         private HashMap<ushortConstantValue*> ushortValueMap;
471         private HashMap<intConstantValue*> intValueMap;
472         private HashMap<uintConstantValue*> uintValueMap;
473         private HashMap<longConstantValue*> longValueMap;
474         private HashMap<ulongConstantValue*> ulongValueMap;
475         private List<UniquePtr<Operand>> operands;
476         private HashMap<ulongLiteralOperand*> literalOperandMap;
477         private HashMap<stringSymbolOperand*> symbolOperandMap;
478     }
479 }