Mercurial > projects > ldc
comparison ir/irtypestruct.cpp @ 1228:79758fd2f48a
Added Doxygen file.
Completely seperated type and symbol generation. Should fix a lot of bugs, but is not yet 100% complete.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail.com> |
---|---|
date | Wed, 15 Apr 2009 20:06:25 +0200 |
parents | |
children | 212ec2d9d176 |
comparison
equal
deleted
inserted
replaced
1215:08f87d8cd101 | 1228:79758fd2f48a |
---|---|
1 #include "llvm/DerivedTypes.h" | |
2 | |
3 #include "aggregate.h" | |
4 #include "declaration.h" | |
5 #include "mtype.h" | |
6 | |
7 #include "gen/irstate.h" | |
8 #include "gen/tollvm.h" | |
9 #include "gen/logger.h" | |
10 #include "gen/utils.h" | |
11 #include "ir/irtypestruct.h" | |
12 | |
13 ////////////////////////////////////////////////////////////////////////////// | |
14 ////////////////////////////////////////////////////////////////////////////// | |
15 ////////////////////////////////////////////////////////////////////////////// | |
16 | |
17 IrTypeAggr::IrTypeAggr(AggregateDeclaration * ad) | |
18 : IrType(ad->type, llvm::OpaqueType::get()), | |
19 aggr(ad) | |
20 { | |
21 } | |
22 | |
23 ////////////////////////////////////////////////////////////////////////////// | |
24 ////////////////////////////////////////////////////////////////////////////// | |
25 ////////////////////////////////////////////////////////////////////////////// | |
26 | |
27 IrTypeStruct::IrTypeStruct(StructDeclaration * sd) | |
28 : IrTypeAggr(sd), | |
29 sd(sd), | |
30 ts((TypeStruct*)sd->type) | |
31 { | |
32 } | |
33 | |
34 ////////////////////////////////////////////////////////////////////////////// | |
35 | |
36 size_t add_zeros(std::vector<const llvm::Type*>& defaultTypes, size_t diff) | |
37 { | |
38 size_t n = defaultTypes.size(); | |
39 while (diff) | |
40 { | |
41 if (global.params.is64bit && diff % 8 == 0) | |
42 { | |
43 defaultTypes.push_back(llvm::Type::Int64Ty); | |
44 diff -= 8; | |
45 } | |
46 else if (diff % 4 == 0) | |
47 { | |
48 defaultTypes.push_back(llvm::Type::Int32Ty); | |
49 diff -= 4; | |
50 } | |
51 else if (diff % 2 == 0) | |
52 { | |
53 defaultTypes.push_back(llvm::Type::Int16Ty); | |
54 diff -= 2; | |
55 } | |
56 else | |
57 { | |
58 defaultTypes.push_back(llvm::Type::Int8Ty); | |
59 diff -= 1; | |
60 } | |
61 } | |
62 return defaultTypes.size() - n; | |
63 } | |
64 | |
65 const llvm::Type* IrTypeStruct::buildType() | |
66 { | |
67 IF_LOG Logger::println("Building struct type %s @ %s", sd->toPrettyChars(), sd->locToChars()); | |
68 LOG_SCOPE; | |
69 | |
70 // find the fields that contribute to the default initializer. | |
71 // these will define the default type. | |
72 | |
73 std::vector<const llvm::Type*> defaultTypes; | |
74 defaultTypes.reserve(16); | |
75 | |
76 size_t offset = 0; | |
77 size_t field_index = 0; | |
78 | |
79 bool packed = (sd->type->alignsize() == 1); | |
80 | |
81 ArrayIter<VarDeclaration> it(sd->fields); | |
82 for (; !it.done(); it.next()) | |
83 { | |
84 VarDeclaration* vd = it.get(); | |
85 | |
86 assert(vd->ir.irField == NULL && "struct inheritance is not allowed, how can this happen?"); | |
87 | |
88 // skip if offset moved backwards | |
89 if (vd->offset < offset) | |
90 { | |
91 IF_LOG Logger::println("Skipping field %s %s (+%u) for default", vd->type->toChars(), vd->toChars(), vd->offset); | |
92 new IrField(vd, 0, vd->offset); | |
93 continue; | |
94 } | |
95 | |
96 IF_LOG Logger::println("Adding default field %s %s (+%u)", vd->type->toChars(), vd->toChars(), vd->offset); | |
97 | |
98 // get next aligned offset for this type | |
99 size_t alignedoffset = offset; | |
100 if (!packed) | |
101 { | |
102 size_t alignsize = vd->type->alignsize(); | |
103 alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1); | |
104 } | |
105 | |
106 // insert explicit padding? | |
107 if (alignedoffset < vd->offset) | |
108 { | |
109 field_index += add_zeros(defaultTypes, vd->offset - alignedoffset); | |
110 } | |
111 | |
112 // add default type | |
113 defaultTypes.push_back(DtoType(vd->type)); | |
114 | |
115 // advance offset to right past this field | |
116 offset = vd->offset + vd->type->size(); | |
117 | |
118 // give field index | |
119 // the IrField creation doesn't really belong here, but it's a trivial operation | |
120 // and it save yet another of these loops. | |
121 IF_LOG Logger::println("Field index: %zu", field_index); | |
122 new IrField(vd, field_index); | |
123 field_index++; | |
124 } | |
125 | |
126 // tail padding? | |
127 if (offset < sd->structsize) | |
128 { | |
129 add_zeros(defaultTypes, sd->structsize - offset); | |
130 } | |
131 | |
132 // build the llvm type | |
133 const llvm::Type* st = llvm::StructType::get(defaultTypes, packed); | |
134 | |
135 // refine type | |
136 llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(st); | |
137 | |
138 // name types | |
139 Type::sir->getState()->module->addTypeName(sd->toPrettyChars(), pa.get()); | |
140 | |
141 #if 0 | |
142 IF_LOG Logger::cout() << "struct type: " << *pa.get() << std::endl; | |
143 #endif | |
144 | |
145 return pa.get(); | |
146 } | |
147 | |
148 ////////////////////////////////////////////////////////////////////////////// |