annotate gen/classes.cpp @ 117:56a21f3e5d3e trunk

[svn r121] Finished ModuleInfo implementation. Static ctors/dtors now work according to spec. Changed class vtable types slightly in some cases. Overridden functions now always take the the type of the first class declaring the method as this parameter. This helps when using headers (w. implementation somewhere else)
author lindquist
date Mon, 26 Nov 2007 04:49:23 +0100
parents 5ba6d286c941
children 9c79b61fb638
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1 #include <sstream>
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
2 #include "gen/llvm.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
3
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
4 #include "mtype.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
5 #include "aggregate.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
6 #include "init.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
7 #include "declaration.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
8
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
9 #include "gen/irstate.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
10 #include "gen/tollvm.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
11 #include "gen/arrays.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
12 #include "gen/logger.h"
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
13 #include "gen/classes.h"
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
14 #include "gen/functions.h"
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
15 #include "gen/runtime.h"
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
16 #include "gen/dvalue.h"
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
17
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
18 //////////////////////////////////////////////////////////////////////////////////////////
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
19
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
20 static void LLVM_AddBaseClassData(BaseClasses* bcs)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
21 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
22 // add base class data members first
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
23 for (int j=0; j<bcs->dim; j++)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
24 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
25 BaseClass* bc = (BaseClass*)(bcs->data[j]);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
26 assert(bc);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
27 if (bc->base->isInterfaceDeclaration())
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
28 continue; // interfaces only has methods
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
29
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
30 LLVM_AddBaseClassData(&bc->base->baseclasses);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
31
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
32 Logger::println("Adding base class members of %s", bc->base->toChars());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
33 LOG_SCOPE;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
34
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
35 for (int k=0; k < bc->base->members->dim; k++) {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
36 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
37 if (dsym->isVarDeclaration())
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
38 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
39 dsym->toObjFile();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
40 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
41 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
42 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
43 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
44
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
45 //////////////////////////////////////////////////////////////////////////////////////////
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
46
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
47 void DtoResolveClass(ClassDeclaration* cd)
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
48 {
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
49 if (cd->llvmResolved) return;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
50 cd->llvmResolved = true;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
51
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
52 // first resolve the base class
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
53 if (cd->baseClass) {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
54 DtoResolveClass(cd->baseClass);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
55 }
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
56
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
57 // resolve interfaces
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
58 if (cd->vtblInterfaces) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
59 for (int i=0; i < cd->vtblInterfaces->dim; i++) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
60 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
61 ClassDeclaration *id = b->base;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
62 DtoResolveClass(id);
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
63 // Fill in vtbl[]
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
64 b->fillVtbl(cd, &b->vtbl, 1);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
65 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
66 }
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
67
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
68 Logger::println("DtoResolveClass(%s)", cd->toPrettyChars());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
69 LOG_SCOPE;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
70
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
71 assert(cd->type->ty == Tclass);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
72 TypeClass* ts = (TypeClass*)cd->type;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
73
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
74 assert(!cd->llvmIRStruct);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
75 IRStruct* irstruct = new IRStruct(ts);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
76 cd->llvmIRStruct = irstruct;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
77
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
78 gIR->structs.push_back(irstruct);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
79 gIR->classes.push_back(cd);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
80
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
81 // add vtable
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
82 ts->llvmVtblType = new llvm::PATypeHolder(llvm::OpaqueType::get());
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
83 const llvm::Type* vtabty = llvm::PointerType::get(ts->llvmVtblType->get());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
84
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
85 std::vector<const llvm::Type*> fieldtypes;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
86 fieldtypes.push_back(vtabty);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
87
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
88 // add monitor
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
89 fieldtypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty));
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
90
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
91 // add interface vtables
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
92 if (cd->vtblInterfaces)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
93 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
94 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
95 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
96 ClassDeclaration *id = b->base;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
97 assert(id->type->ty == Tclass);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
98 TypeClass* itc = (TypeClass*)id->type;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
99 const llvm::Type* ivtblTy = llvm::PointerType::get(itc->llvmVtblType->get());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
100 fieldtypes.push_back(ivtblTy);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
101
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
102 // add this interface to the map
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
103 IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get()));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
104 irstruct->interfaces.insert(std::make_pair(id, iri));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
105 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
106
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
107 // base classes first
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
108 LLVM_AddBaseClassData(&cd->baseclasses);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
109
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
110 // then add own members
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
111 for (int k=0; k < cd->members->dim; k++) {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
112 Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
113 dsym->toObjFile();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
114 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
115
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
116 // add field types
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
117 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
118 fieldtypes.push_back(i->second.type);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
119 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
120
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
121 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
122 // refine abstract types for stuff like: class C {C next;}
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
123 assert(irstruct->recty != 0);
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
124
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
125 llvm::PATypeHolder& spa = irstruct->recty;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
126 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
127 structtype = isaStruct(spa.get());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
128
103
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
129 if (!ts->llvmType)
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
130 ts->llvmType = new llvm::PATypeHolder(structtype);
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
131 else
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
132 *ts->llvmType = structtype;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
133
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
134 if (cd->isNested()) {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
135 assert(0 && "nested classes not implemented");
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
136 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
137 else {
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
138 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
139 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
140
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
141 // build interface info type
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
142 std::vector<const llvm::Type*> infoTypes;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
143 // ClassInfo classinfo
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
144 ClassDeclaration* cinfod = ClassDeclaration::classinfo;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
145 DtoResolveClass(cinfod);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
146 infoTypes.push_back(llvm::PointerType::get(cinfod->type->llvmType->get()));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
147 // void*[] vtbl
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
148 std::vector<const llvm::Type*> infoVtbltypes;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
149 infoVtbltypes.push_back(DtoSize_t());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
150 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
151 infoVtbltypes.push_back(byteptrptrty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
152 infoTypes.push_back(llvm::StructType::get(infoVtbltypes));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
153 // int offset
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
154 infoTypes.push_back(llvm::Type::Int32Ty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
155 // create type
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
156 const llvm::StructType* infoTy = llvm::StructType::get(infoTypes);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
157
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
158 // create vtable type
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
159 llvm::GlobalVariable* svtblVar = 0;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
160 std::vector<const llvm::Type*> sinits_ty;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
161
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
162 for (int k=0; k < cd->vtbl.dim; k++)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
163 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
164 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k];
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
165 assert(dsym);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
166 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
167
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
168 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
169 DtoResolveFunction(fd);
117
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
170 //assert(fd->type->ty == Tfunction);
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
171 //TypeFunction* tf = (TypeFunction*)fd->type;
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
172 //const llvm::Type* fpty = llvm::PointerType::get(tf->llvmType->get());
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
173 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd);
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
174 const llvm::Type* vfpty = llvm::PointerType::get(vfty);
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
175 sinits_ty.push_back(vfpty);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
176 }
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
177 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
178 Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars());
103
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
179 const llvm::Type* cinfoty;
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
180 if (cd->isInterfaceDeclaration()) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
181 cinfoty = infoTy;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
182 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
183 else if (cd != cinfod) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
184 DtoResolveClass(cinfod);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
185 cinfoty = cinfod->type->llvmType->get();
103
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
186 }
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
187 else {
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
188 // this is the ClassInfo class, the type is this type
103
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
189 cinfoty = ts->llvmType->get();
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
190 }
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
191 const llvm::Type* cty = llvm::PointerType::get(cinfoty);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
192 sinits_ty.push_back(cty);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
193 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
194 else
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
195 assert(0);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
196 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
197
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
198 assert(!sinits_ty.empty());
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
199 const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
200
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
201 std::string styname(cd->mangle());
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
202 styname.append("__vtblType");
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
203 gIR->module->addTypeName(styname, svtbl_ty);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
204
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
205 // refine for final vtable type
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
206 llvm::cast<llvm::OpaqueType>(ts->llvmVtblType->get())->refineAbstractTypeTo(svtbl_ty);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
207
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
208 gIR->classes.pop_back();
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
209 gIR->structs.pop_back();
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
210
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
211 gIR->declareList.push_back(cd);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
212 }
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
213
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
214 //////////////////////////////////////////////////////////////////////////////////////////
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
215
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
216 void DtoDeclareClass(ClassDeclaration* cd)
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
217 {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
218 if (cd->llvmDeclared) return;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
219 cd->llvmDeclared = true;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
220
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
221 Logger::println("DtoDeclareClass(%s)", cd->toPrettyChars());
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
222 LOG_SCOPE;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
223
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
224 assert(cd->type->ty == Tclass);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
225 TypeClass* ts = (TypeClass*)cd->type;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
226
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
227 assert(cd->llvmIRStruct);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
228 IRStruct* irstruct = cd->llvmIRStruct;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
229
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
230 gIR->structs.push_back(irstruct);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
231 gIR->classes.push_back(cd);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
232
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
233 bool needs_definition = false;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
234 if (cd->parent->isModule()) {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
235 needs_definition = (cd->getModule() == gIR->dmodule);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
236 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
237
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
238 // interface vtables are emitted by the class implementing them
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
239 // also interfaces have no static initializer
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
240 if (!cd->isInterfaceDeclaration()) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
241 // vtable
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
242 std::string varname("_D");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
243 varname.append(cd->mangle());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
244 varname.append("6__vtblZ");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
245
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
246 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
247
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
248 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
249 cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
250
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
251 // build interface info type
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
252 std::vector<const llvm::Type*> types;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
253 // ClassInfo classinfo
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
254 ClassDeclaration* cd2 = ClassDeclaration::classinfo;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
255 DtoResolveClass(cd2);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
256 types.push_back(llvm::PointerType::get(cd2->type->llvmType->get()));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
257 // void*[] vtbl
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
258 std::vector<const llvm::Type*> vtbltypes;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
259 vtbltypes.push_back(DtoSize_t());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
260 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
261 vtbltypes.push_back(byteptrptrty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
262 types.push_back(llvm::StructType::get(vtbltypes));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
263 // int offset
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
264 types.push_back(llvm::Type::Int32Ty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
265 // create type
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
266 const llvm::StructType* infoTy = llvm::StructType::get(types);
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
267
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
268 // interface info array
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
269 if (needs_definition && cd->vtblInterfaces->dim > 0) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
270 // symbol name
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
271 std::string nam = "_D";
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
272 nam.append(cd->mangle());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
273 nam.append("16__interfaceInfosZ");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
274 // resolve array type
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
275 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
276 // declare global
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
277 irstruct->interfaceInfosTy = arrTy;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
278 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, llvm::GlobalValue::InternalLinkage, 0, nam, gIR->module);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
279 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
280
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
281 // interface vtables
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
282 unsigned idx = 0;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
283 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
284 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
285 ClassDeclaration* id = i->first;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
286 IRInterface* iri = i->second;
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
287
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
288 std::string nam("_D");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
289 nam.append(cd->mangle());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
290 nam.append("11__interface");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
291 nam.append(id->mangle());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
292 nam.append("6__vtblZ");
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
293
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
294 assert(iri->vtblTy);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
295 iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
296 iri->infoTy = infoTy;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
297 llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
298 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
299 idx++;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
300 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
301
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
302 // init
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
303 std::string initname("_D");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
304 initname.append(cd->mangle());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
305 initname.append("6__initZ");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
306
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
307 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
308 ts->llvmInit = initvar;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
309 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
310
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
311 gIR->classes.pop_back();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
312 gIR->structs.pop_back();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
313
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
314 gIR->constInitList.push_back(cd);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
315 if (needs_definition)
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
316 gIR->defineList.push_back(cd);
103
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
317
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
318 // classinfo
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
319 DtoDeclareClassInfo(cd);
106
5b5194b25f33 [svn r110] Fixed typeinfo for classes.
lindquist
parents: 103
diff changeset
320
5b5194b25f33 [svn r110] Fixed typeinfo for classes.
lindquist
parents: 103
diff changeset
321 // typeinfo
5b5194b25f33 [svn r110] Fixed typeinfo for classes.
lindquist
parents: 103
diff changeset
322 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule)
5b5194b25f33 [svn r110] Fixed typeinfo for classes.
lindquist
parents: 103
diff changeset
323 cd->type->getTypeInfo(NULL);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
324 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
325
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
326 //////////////////////////////////////////////////////////////////////////////////////////
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
327
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
328 void DtoConstInitClass(ClassDeclaration* cd)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
329 {
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
330 if (cd->llvmInitialized) return;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
331 cd->llvmInitialized = true;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
332
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
333 if (cd->isInterfaceDeclaration())
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
334 return; // nothing to do
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
335
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
336 Logger::println("DtoConstInitClass(%s)", cd->toPrettyChars());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
337 LOG_SCOPE;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
338
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
339 IRStruct* irstruct = cd->llvmIRStruct;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
340 gIR->structs.push_back(irstruct);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
341 gIR->classes.push_back(cd);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
342
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
343 // make sure each offset knows its default initializer
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
344 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
345 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
346 IRStruct::Offset* so = &i->second;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
347 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
348 so->init = finit;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
349 so->var->llvmConstInit = finit;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
350 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
351
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
352 // fill out fieldtypes/inits
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
353 std::vector<llvm::Constant*> fieldinits;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
354
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
355 // first field is always the vtable
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
356 assert(cd->llvmVtbl != 0);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
357 fieldinits.push_back(cd->llvmVtbl);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
358
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
359 // then comes monitor
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
360 fieldinits.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)));
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
361
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
362 // next comes interface vtables
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
363 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
364 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
365 IRInterface* iri = i->second;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
366 assert(iri->vtbl);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
367 fieldinits.push_back(iri->vtbl);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
368 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
369
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
370 // rest
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
371 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
372 Logger::println("adding fieldinit for: %s", i->second.var->toChars());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
373 fieldinits.push_back(i->second.init);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
374 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
375
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
376 // get the struct (class) type
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
377 assert(cd->type->ty == Tclass);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
378 TypeClass* ts = (TypeClass*)cd->type;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
379 const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
117
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
380 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
381
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
382 // generate initializer
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
383 #if 0
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
384 Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
385
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
386 for(size_t i=0; i<structtype->getNumElements(); ++i) {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
387 Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n';
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
388 }
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
389
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
390 for(size_t i=0; i<fieldinits.size(); ++i) {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
391 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n';
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
392 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
393 #endif
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
394
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
395 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
396 assert(_init);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
397 cd->llvmInitZ = _init;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
398
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
399 // generate vtable initializer
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
400 std::vector<llvm::Constant*> sinits;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
401
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
402 for (int k=0; k < cd->vtbl.dim; k++)
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
403 {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
404 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k];
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
405 assert(dsym);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
406 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
407
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
408 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
409 DtoForceDeclareDsymbol(fd);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
410 assert(fd->llvmValue);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
411 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
117
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
412 // cast if necessary (overridden method)
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
413 if (c->getType() != vtbltype->getElementType(k))
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
414 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
415 sinits.push_back(c);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
416 }
103
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
417 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
418 assert(cd->llvmClass);
855adfdb8d38 [svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents: 102
diff changeset
419 llvm::Constant* c = cd->llvmClass;
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
420 sinits.push_back(c);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
421 }
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
422 else
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
423 assert(0);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
424 }
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
425
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
426 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
427
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
428 #if 0
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
429 for (size_t i=0; i< sinits.size(); ++i)
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
430 {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
431 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n';
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
432 Logger::cout() << "init [" << i << "] = " << *sinits[i]->getType() << '\n';
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
433 assert(svtbl_ty->getElementType(i) == sinits[i]->getType());
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
434 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
435 #endif
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
436
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
437 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
438 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
439
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
440 // create interface vtable const initalizers
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
441 int idx = 2;
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
442 int idxScale = PTRSIZE;
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
443 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
444 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
445 ClassDeclaration* id = i->first;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
446 assert(id->type->ty == Tclass);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
447 TypeClass* its = (TypeClass*)id->type;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
448
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
449 IRInterface* iri = i->second;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
450 BaseClass* b = iri->base;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
451
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
452 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
453
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
454 // generate interface info initializer
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
455 std::vector<llvm::Constant*> infoInits;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
456 // classinfo
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
457 assert(id->llvmClass);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
458 llvm::Constant* c = id->llvmClass;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
459 infoInits.push_back(c);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
460 // vtbl
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
461 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
462 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
463 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
464 infoInits.push_back(c);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
465 // offset
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
466 infoInits.push_back(DtoConstInt(idx*idxScale));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
467 // create interface info initializer constant
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
468 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
469
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
470 // generate vtable initializer
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
471 std::vector<llvm::Constant*> iinits;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
472
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
473 // add interface info
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
474 iinits.push_back(iri->info);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
475
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
476 for (int k=1; k < b->vtbl.dim; k++)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
477 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
478 Logger::println("interface vtbl const init nr. %d", k);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
479 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k];
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
480 FuncDeclaration* fd = dsym->isFuncDeclaration();
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
481 assert(fd);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
482 DtoForceDeclareDsymbol(fd);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
483 assert(fd->llvmValue);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
484 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
485 // we have to bitcast, as the type created in ResolveClass expects a different this type
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
486 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
487 iinits.push_back(c);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
488 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
489
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
490 #if 1
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
491 for (size_t x=0; x< iinits.size(); ++x)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
492 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
493 Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n";
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
494 Logger::cout() << "init [" << x << "] = " << *iinits[x] << "\n\n";
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
495 assert(ivtbl_ty->getElementType(x) == iinits[x]->getType());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
496 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
497 #endif
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
498
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
499 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
500 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
501
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
502 idx++;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
503 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
504
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
505 gIR->classes.pop_back();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
506 gIR->structs.pop_back();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
507 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
508
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
509 //////////////////////////////////////////////////////////////////////////////////////////
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
510
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
511 void DtoDefineClass(ClassDeclaration* cd)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
512 {
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
513 if (cd->llvmDefined) return;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
514 cd->llvmDefined = true;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
515
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
516 Logger::println("DtoDefineClass(%s)", cd->toPrettyChars());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
517 LOG_SCOPE;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
518
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
519 // get the struct (class) type
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
520 assert(cd->type->ty == Tclass);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
521 TypeClass* ts = (TypeClass*)cd->type;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
522
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
523 bool def = false;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
524 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) {
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
525 // interfaces don't have initializers
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
526 if (!cd->isInterfaceDeclaration()) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
527 ts->llvmInit->setInitializer(cd->llvmInitZ);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
528 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
529
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
530 // initialize interface vtables
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
531 IRStruct* irstruct = cd->llvmIRStruct;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
532 std::vector<llvm::Constant*> infoInits;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
533 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
534 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
535 IRInterface* iri = i->second;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
536 iri->vtbl->setInitializer(iri->vtblInit);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
537 infoInits.push_back(iri->infoInit);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
538 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
539 // initialize interface info array
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
540 if (!infoInits.empty()) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
541 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
542 irstruct->interfaceInfos->setInitializer(arrInit);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
543 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
544 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
545 def = true;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
546 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
547
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
548 // generate classinfo
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
549 if (def) DtoDefineClassInfo(cd);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
550 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
551
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
552 //////////////////////////////////////////////////////////////////////////////////////////
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
553
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
554 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
555 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
556 Array* arr = &tc->sym->dtors;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
557 for (size_t i=0; i<arr->dim; i++)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
558 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
559 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
560 assert(fd->llvmValue);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
561 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
562 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
563 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
564
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
565 //////////////////////////////////////////////////////////////////////////////////////////
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
566
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
567 void DtoInitClass(TypeClass* tc, llvm::Value* dst)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
568 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
569 assert(gIR);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
570
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
571 assert(tc->llvmType);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
572 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
573 uint64_t n = gTargetData->getTypeSize(tc->llvmType->get()) - size_t_size;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
574
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
575 // set vtable field
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
576 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
577 assert(tc->sym->llvmVtbl);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
578 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
579
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
580 // copy the static initializer
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
581 if (n > 0) {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
582 assert(tc->llvmInit);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
583 assert(dst->getType() == tc->llvmInit->getType());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
584
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
585 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
586
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
587 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
588 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
589
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
590 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
591 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
592
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
593 llvm::Function* fn = LLVM_DeclareMemCpy32();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
594 std::vector<llvm::Value*> llargs;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
595 llargs.resize(4);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
596 llargs[0] = dstarr;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
597 llargs[1] = srcarr;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
598 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
599 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
600
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
601 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
602 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
603 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
604
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
605 //////////////////////////////////////////////////////////////////////////////////////////
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
606
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
607 DValue* DtoCastClass(DValue* val, Type* _to)
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
608 {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
609 Type* to = DtoDType(_to);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
610 if (to->ty == Tpointer) {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
611 const llvm::Type* tolltype = DtoType(_to);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
612 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
613 return new DImValue(_to, rval);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
614 }
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
615
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
616 assert(to->ty == Tclass);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
617 TypeClass* tc = (TypeClass*)to;
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
618
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
619 Type* from = DtoDType(val->getType());
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
620 TypeClass* fc = (TypeClass*)from;
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
621
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
622 if (tc->sym->isInterfaceDeclaration()) {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
623 assert(!fc->sym->isInterfaceDeclaration());
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
624 return DtoDynamicCastObject(val, _to);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
625 }
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
626 else {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
627 int poffset;
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
628 if (fc->sym->isInterfaceDeclaration()) {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
629 return DtoCastInterfaceToObject(val, _to);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
630 }
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
631 else if (tc->sym->isBaseOf(fc->sym,NULL)) {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
632 const llvm::Type* tolltype = DtoType(_to);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
633 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
634 return new DImValue(_to, rval);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
635 }
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
636 else {
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
637 return DtoDynamicCastObject(val, _to);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
638 }
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
639 }
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
640 }
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
641
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
642 //////////////////////////////////////////////////////////////////////////////////////////
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
643
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
644 DValue* DtoDynamicCastObject(DValue* val, Type* _to)
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
645 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
646 // call:
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
647 // Object _d_dynamic_cast(Object o, ClassInfo c)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
648
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
649 DtoForceDeclareDsymbol(ClassDeclaration::object);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
650 DtoForceDeclareDsymbol(ClassDeclaration::classinfo);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
651
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
652 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
653 const llvm::FunctionType* funcTy = func->getFunctionType();
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
654
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
655 std::vector<llvm::Value*> args;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
656
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
657 // Object o
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
658 llvm::Value* tmp = val->getRVal();
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
659 tmp = DtoBitCast(tmp, funcTy->getParamType(0));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
660 args.push_back(tmp);
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
661 assert(funcTy->getParamType(0) == tmp->getType());
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
662
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
663 // ClassInfo c
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
664 TypeClass* to = (TypeClass*)DtoDType(_to);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
665 DtoForceDeclareDsymbol(to->sym);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
666 assert(to->sym->llvmClass);
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
667 tmp = to->sym->llvmClass;
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
668 // unfortunately this is needed as the implementation of object differs somehow from the declaration
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
669 // this could happen in user code as well :/
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
670 tmp = DtoBitCast(tmp, funcTy->getParamType(1));
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
671 args.push_back(tmp);
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
672 assert(funcTy->getParamType(1) == tmp->getType());
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
673
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
674 // call it
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
675 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp");
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
676
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
677 // cast return value
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
678 ret = DtoBitCast(ret, DtoType(_to));
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
679
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
680 return new DImValue(_to, ret);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
681 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
682
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
683 //////////////////////////////////////////////////////////////////////////////////////////
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
684
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
685 DValue* DtoCastInterfaceToObject(DValue* val, Type* to)
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
686 {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
687 // call:
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
688 // Object _d_toObject(void* p)
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
689
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
690 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
691 const llvm::FunctionType* funcTy = func->getFunctionType();
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
692
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
693 // void* p
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
694 llvm::Value* tmp = val->getRVal();
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
695 tmp = DtoBitCast(tmp, funcTy->getParamType(0));
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
696
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
697 // call it
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
698 llvm::Value* ret = gIR->ir->CreateCall(func, tmp, "tmp");
114
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
699
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
700 // cast return value
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
701 if (to != NULL)
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
702 ret = DtoBitCast(ret, DtoType(to));
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
703 else
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
704 to = ClassDeclaration::object->type;
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
705
5880c12dba83 [svn r118] Fixed dynamic casts.
lindquist
parents: 113
diff changeset
706 return new DImValue(to, ret);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
707 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
708
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
709 //////////////////////////////////////////////////////////////////////////////////////////
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
710
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
711 void DtoDeclareClassInfo(ClassDeclaration* cd)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
712 {
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
713 if (cd->llvmClassDeclared) return;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
714 cd->llvmClassDeclared = true;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
715
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
716 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars());
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
717 LOG_SCOPE;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
718
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
719 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
720 DtoResolveClass(cinfo);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
721
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
722 std::string gname("_D");
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
723 gname.append(cd->mangle());
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
724 if (!cd->isInterfaceDeclaration())
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
725 gname.append("7__ClassZ");
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
726 else
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
727 gname.append("11__InterfaceZ");
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
728
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
729 const llvm::Type* st = cinfo->type->llvmType->get();
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
730
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
731 cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
732 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
733
110
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
734 static llvm::Constant* build_offti_entry(VarDeclaration* vd)
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
735 {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
736 std::vector<const llvm::Type*> types;
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
737 std::vector<llvm::Constant*> inits;
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
738
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
739 types.push_back(DtoSize_t());
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
740
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
741 size_t offset = vd->offset; // TODO might not be the true offset
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
742 // dmd only accounts for the vtable, not classinfo or monitor
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
743 if (global.params.is64bit)
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
744 offset += 8;
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
745 else
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
746 offset += 4;
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
747 inits.push_back(DtoConstSize_t(offset));
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
748
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
749 vd->type->getTypeInfo(NULL);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
750 assert(vd->type->vtinfo);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
751 DtoForceDeclareDsymbol(vd->type->vtinfo);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
752 llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
753
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
754 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
755 Logger::cout() << "tiTy = " << *tiTy << '\n';
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
756
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
757 types.push_back(tiTy);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
758 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy));
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
759
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
760 const llvm::StructType* sTy = llvm::StructType::get(types);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
761 return llvm::ConstantStruct::get(sTy, inits);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
762 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
763
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
764 static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* init)
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
765 {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
766 const llvm::StructType* initTy = isaStruct(init->getType());
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
767 assert(initTy);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
768
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
769 std::vector<llvm::Constant*> arrayInits;
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
770 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
771 {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
772 if (cd2->members)
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
773 {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
774 for (size_t i = 0; i < cd2->members->dim; i++)
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
775 {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
776 Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
112
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
777 if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough?
110
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
778 {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
779 llvm::Constant* c = build_offti_entry(vd);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
780 assert(c);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
781 arrayInits.push_back(c);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
782 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
783 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
784 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
785 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
786
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
787 size_t ninits = arrayInits.size();
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
788 llvm::Constant* size = DtoConstSize_t(ninits);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
789 llvm::Constant* ptr;
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
790
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
791 if (ninits > 0) {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
792 // OffsetTypeInfo type
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
793 std::vector<const llvm::Type*> elemtypes;
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
794 elemtypes.push_back(DtoSize_t());
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
795 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
796 elemtypes.push_back(tiTy);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
797 const llvm::StructType* sTy = llvm::StructType::get(elemtypes);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
798
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
799 // array type
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
800 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
801 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
802
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
803 std::string name(cd->type->vtinfo->toChars());
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
804 name.append("__OffsetTypeInfos");
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
805 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
806 ptr = llvm::ConstantExpr::getBitCast(gvar, llvm::PointerType::get(sTy));
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
807 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
808 else {
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
809 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
810 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
811
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
812 return DtoConstSlice(size, ptr);
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
813 }
e8da7856a260 [svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents: 106
diff changeset
814
112
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
815 static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
816 {
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
817 // construct the function
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
818 std::vector<const llvm::Type*> paramTypes;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
819 paramTypes.push_back(llvm::PointerType::get(cd->type->llvmType->get()));
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
820
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
821 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
822
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
823 if (cd->dtors.dim == 0) {
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
824 return llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
825 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
826 else if (cd->dtors.dim == 1) {
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
827 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
828 DtoForceDeclareDsymbol(d);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
829 assert(d->llvmValue);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
830 return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), llvm::PointerType::get(llvm::Type::Int8Ty));
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
831 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
832
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
833 std::string gname("_D");
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
834 gname.append(cd->mangle());
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
835 gname.append("12__destructorMFZv");
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
836
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
837 llvm::Function* func = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, gname, gIR->module);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
838 llvm::Value* thisptr = func->arg_begin();
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
839 thisptr->setName("this");
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
840
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
841 llvm::BasicBlock* bb = new llvm::BasicBlock("entry", func);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
842 LLVMBuilder builder(bb);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
843
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
844 for (size_t i = 0; i < cd->dtors.dim; i++)
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
845 {
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
846 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
847 DtoForceDeclareDsymbol(d);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
848 assert(d->llvmValue);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
849 builder.CreateCall(d->llvmValue, thisptr);
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
850 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
851 builder.CreateRetVoid();
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
852
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
853 return llvm::ConstantExpr::getBitCast(func, llvm::PointerType::get(llvm::Type::Int8Ty));
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
854 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
855
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
856 static uint build_classinfo_flags(ClassDeclaration* cd)
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
857 {
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
858 // adapted from original dmd code
112
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
859 uint flags = 0;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
860 //flags |= isCOMclass(); // IUnknown
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
861 bool hasOffTi = false;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
862 if (cd->ctor) flags |= 8;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
863 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
864 {
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
865 if (cd2->members)
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
866 {
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
867 for (size_t i = 0; i < cd2->members->dim; i++)
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
868 {
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
869 Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
870 if (sm->isVarDeclaration()) // is this enough?
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
871 hasOffTi = true;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
872 //printf("sm = %s %s\n", sm->kind(), sm->toChars());
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
873 if (sm->hasPointers())
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
874 goto L2;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
875 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
876 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
877 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
878 flags |= 2; // no pointers
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
879 L2:
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
880 if (hasOffTi)
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
881 flags |= 4;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
882 return flags;
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
883 }
368547b1cbe6 [svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents: 111
diff changeset
884
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
885 void DtoDefineClassInfo(ClassDeclaration* cd)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
886 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
887 // The layout is:
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
888 // {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
889 // void **vptr;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
890 // monitor_t monitor;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
891 // byte[] initializer; // static initialization data
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
892 // char[] name; // class name
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
893 // void *[] vtbl;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
894 // Interface[] interfaces;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
895 // ClassInfo *base; // base class
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
896 // void *destructor;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
897 // void *invariant; // class invariant
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
898 // uint flags;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
899 // void *deallocator;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
900 // OffsetTypeInfo[] offTi;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
901 // void *defaultConstructor;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
902 // }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
903
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
904 if (cd->llvmClassDefined) return;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
905 cd->llvmClassDefined = true;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
906
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
907 Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
908 LOG_SCOPE;
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
909
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
910 assert(cd->type->ty == Tclass);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
911 assert(cd->llvmClass);
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
912
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
913 TypeClass* cdty = (TypeClass*)cd->type;
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
914 if (!cd->isInterfaceDeclaration()) {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
915 assert(cd->llvmInitZ);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
916 assert(cd->llvmVtbl);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
917 assert(cd->llvmConstVtbl);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
918 assert(cdty->llvmInit);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
919 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
920
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
921 // holds the list of initializers for llvm
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
922 std::vector<llvm::Constant*> inits;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
923
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
924 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
925 DtoForceConstInitDsymbol(cinfo);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
926 assert(cinfo->llvmInitZ);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
927
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
928 llvm::Constant* c;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
929
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
930 // own vtable
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
931 c = cinfo->llvmInitZ->getOperand(0);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
932 assert(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
933 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
934
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
935 // monitor
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
936 c = cinfo->llvmInitZ->getOperand(1);
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
937 inits.push_back(c);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
938
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
939 // byte[] init
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
940 const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
941 if (cd->isInterfaceDeclaration()) {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
942 c = cinfo->llvmInitZ->getOperand(2);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
943 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
944 else {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
945 c = llvm::ConstantExpr::getBitCast(cdty->llvmInit, byteptrty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
946 assert(!cd->llvmInitZ->getType()->isAbstract());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
947 size_t initsz = gTargetData->getTypeSize(cd->llvmInitZ->getType());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
948 c = DtoConstSlice(DtoConstSize_t(initsz), c);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
949 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
950 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
951
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
952 // class name
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
953 // from dmd
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
954 char *name = cd->ident->toChars();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
955 size_t namelen = strlen(name);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
956 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0))
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
957 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
958 name = cd->toPrettyChars();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
959 namelen = strlen(name);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
960 }
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
961 c = DtoConstString(name);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
962 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
963
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
964 // vtbl array
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
965 if (cd->isInterfaceDeclaration()) {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
966 c = cinfo->llvmInitZ->getOperand(4);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
967 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
968 else {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
969 const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
970 assert(!cd->llvmVtbl->getType()->isAbstract());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
971 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
972 assert(!cd->llvmConstVtbl->getType()->isAbstract());
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
973 size_t vtblsz = cd->llvmConstVtbl->getType()->getNumElements();
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
974 c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
975 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
976 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
977
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
978 // interfaces array
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
979 IRStruct* irstruct = cd->llvmIRStruct;
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
980 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
981 c = cinfo->llvmInitZ->getOperand(5);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
982 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
983 else {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
984 const llvm::Type* t = cinfo->llvmInitZ->getOperand(5)->getType()->getContainedType(1);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
985 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
986 size_t iisz = irstruct->interfaceInfosTy->getNumElements();
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
987 c = DtoConstSlice(DtoConstSize_t(iisz), c);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
988 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
989 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
990
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
991 // base classinfo
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
992 if (cd->baseClass && !cd->isInterfaceDeclaration()) {
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
993 DtoDeclareClassInfo(cd->baseClass);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
994 c = cd->baseClass->llvmClass;
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
995 assert(c);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
996 inits.push_back(c);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
997 }
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
998 else {
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
999 // null
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1000 c = cinfo->llvmInitZ->getOperand(6);
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
1001 inits.push_back(c);
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
1002 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1003
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1004 // destructor
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1005 if (cd->isInterfaceDeclaration()) {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1006 c = cinfo->llvmInitZ->getOperand(7);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1007 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1008 else {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1009 c = build_class_dtor(cd);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1010 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1011 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1012
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1013 // invariant
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
1014 // TODO
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1015 c = cinfo->llvmInitZ->getOperand(8);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1016 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1017
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1018 // uint flags
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1019 if (cd->isInterfaceDeclaration()) {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1020 c = cinfo->llvmInitZ->getOperand(9);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1021 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1022 else {
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1023 uint flags = build_classinfo_flags(cd);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1024 c = DtoConstUint(flags);
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1025 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1026 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1027
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1028 // allocator
102
027b8d8b71ec [svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents: 100
diff changeset
1029 // TODO
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1030 c = cinfo->llvmInitZ->getOperand(10);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1031 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1032
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1033 // offset typeinfo
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1034 if (cd->isInterfaceDeclaration()) {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1035 c = cinfo->llvmInitZ->getOperand(11);
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1036 }
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1037 else {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1038 c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(11));
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1039 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1040 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1041
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1042 // default constructor
113
27b9f749d9fe [svn r117] Initial working implementation of interfaces.
lindquist
parents: 112
diff changeset
1043 if (cd->defaultCtor && !cd->isInterfaceDeclaration()) {
111
a7ae554ce4f4 [svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents: 110
diff changeset
1044 DtoForceDeclareDsymbol(cd->defaultCtor);
a7ae554ce4f4 [svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents: 110
diff changeset
1045 c = isaConstant(cd->defaultCtor->llvmValue);
117
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
1046 const llvm::Type* toTy = cinfo->llvmInitZ->getOperand(12)->getType();
56a21f3e5d3e [svn r121] Finished ModuleInfo implementation.
lindquist
parents: 115
diff changeset
1047 c = llvm::ConstantExpr::getBitCast(c, toTy);
111
a7ae554ce4f4 [svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents: 110
diff changeset
1048 }
a7ae554ce4f4 [svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents: 110
diff changeset
1049 else {
115
5ba6d286c941 [svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents: 114
diff changeset
1050 c = cinfo->llvmInitZ->getOperand(12);
111
a7ae554ce4f4 [svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents: 110
diff changeset
1051 }
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1052 inits.push_back(c);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1053
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1054 /*size_t n = inits.size();
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1055 for (size_t i=0; i<n; ++i)
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1056 {
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1057 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n';
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1058 }*/
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1059
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1060 // build the initializer
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1061 const llvm::StructType* st = isaStruct(cinfo->llvmInitZ->getType());
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1062 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1063 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1064
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1065 cd->llvmClassZ = finalinit;
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1066 cd->llvmClass->setInitializer(finalinit);
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents:
diff changeset
1067 }