Joos1W Compiler Framework
Type.cc
1 #include "tir/Type.h"
2 
3 #include <iostream>
4 #include <ostream>
5 
6 #include "tir/Constant.h"
7 
8 namespace tir {
9 
10 static_assert(sizeof(IntegerType) == sizeof(Type));
11 static_assert(sizeof(FunctionType) == sizeof(Type));
12 static_assert(sizeof(ArrayType) == sizeof(Type));
13 static_assert(sizeof(StructType) == sizeof(Type));
14 
15 Type* Type::getInt1Ty(Context& ctx) { return IntegerType::get(ctx, 1); }
16 Type* Type::getInt8Ty(Context& ctx) { return IntegerType::get(ctx, 8); }
17 Type* Type::getInt16Ty(Context& ctx) { return IntegerType::get(ctx, 16); }
18 Type* Type::getInt32Ty(Context& ctx) { return IntegerType::get(ctx, 32); }
19 
20 std::ostream& Type::print(std::ostream& os) const {
21  if(isIntegerType()) {
22  os << "i" << static_cast<const IntegerType*>(this)->getBitWidth();
23  } else if(isFunctionType()) {
24  os << "function";
25  } else if(isPointerType()) {
26  os << "ptr*";
27  } else if(isArrayType()) {
28  auto ty = static_cast<const ArrayType*>(this);
29  os << "[" << ty->getLength() << " x " << *ty->getElementType() << "]";
30  } else if(isStructType()) {
31  // Get the struct name in the context
32  os << "struct";
33  int i = 0;
34  for(auto ty : ctx_->pimpl().structTypes) {
35  if(ty == this) {
36  os << "." << i;
37  break;
38  }
39  i++;
40  }
41  } else if(isVoidType()) {
42  os << "void";
43  } else {
44  os << "unknown";
45  }
46  return os;
47 }
48 
49 void Type::dump() const {
50  print(std::cerr);
51  std::cerr << std::endl;
52 }
53 
54 std::ostream& StructType::printDetail(std::ostream& os) const {
55  os << "type " << *this << " = ";
56  os << "struct {";
57  bool isFirst = true;
58  for(auto& elem : this->getElements()) {
59  if(!isFirst) os << ", ";
60  isFirst = false;
61  elem->print(os);
62  }
63  os << "}";
64  return os;
65 }
66 
67 std::ostream& operator<<(std::ostream& os, const Type& type) {
68  return type.print(os);
69 }
70 
71 Type* StructType::getIndexedType(utils::range_ref<Value*> indices) {
72  int i = 0;
73  Type* subTy = this;
74  indices.for_each([&](auto* idx) {
75  if(subTy->isStructType()) {
76  subTy = cast<StructType>(subTy)->getTypeAtIndex(
77  cast<ConstantInt>(idx)->zextValue());
78  } else if(subTy->isArrayType()) {
79  subTy = cast<ArrayType>(subTy)->getElementType();
80  } else {
81  assert(false && "Invalid index for GEP");
82  }
83  i++;
84  });
85  return subTy;
86 }
87 
88 } // namespace tir