annotate dmd/BaseClass.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 7427ded8caf7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1 module dmd.BaseClass;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3 import dmd.Type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
4 import dmd.PROT;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
5 import dmd.ClassDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
6 import dmd.Array;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
7 import dmd.TY;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
8 import dmd.TypeFunction;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
9 import dmd.Dsymbol;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
10 import dmd.FuncDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
11 import dmd.ArrayTypes;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
12
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
13 import core.stdc.stdlib;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
14 import core.stdc.string;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
15
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
16 class BaseClass
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
17 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
18 Type type; // (before semantic processing)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
19 PROT protection; // protection for the base interface
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
20
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
21 ClassDeclaration base;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
22 int offset; // 'this' pointer offset
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
23 Array vtbl; // for interfaces: Array of FuncDeclaration's
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
24 // making up the vtbl[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
25
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
26 //int baseInterfaces_dim;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
27 BaseClass[] baseInterfaces; // if BaseClass is an interface, these
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
28 // are a copy of the InterfaceDeclaration::interfaces
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
29
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
30 this()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
31 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
32 vtbl = new Array();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
33 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
34
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
35 this(Type type, PROT protection)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
36 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
37 //printf("BaseClass(this = %p, '%s')\n", this, type->toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
38 this.type = type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
39 this.protection = protection;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
40
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
41 vtbl = new Array();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
42 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
43
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
44 /****************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
45 * Fill in vtbl[] for base class based on member functions of class cd.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
46 * Input:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
47 * vtbl if !=null, fill it in
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
48 * newinstance !=0 means all entries must be filled in by members
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
49 * of cd, not members of any base classes of cd.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
50 * Returns:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
51 * true if any entries were filled in by members of cd (not exclusively
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
52 * by base classes)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
53 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
54 bool fillVtbl(ClassDeclaration cd, Array vtbl, int newinstance)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
55 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
56 ClassDeclaration id = base;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
57 int j;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
58 bool result = false;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
59
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
60 //printf("BaseClass.fillVtbl(this='%s', cd='%s')\n", base.toChars(), cd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
61 if (vtbl)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
62 vtbl.setDim(base.vtbl.dim);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
63
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
64 // first entry is ClassInfo reference
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
65 for (j = base.vtblOffset(); j < base.vtbl.dim; j++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
66 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
67 FuncDeclaration ifd = (cast(Dsymbol)base.vtbl.data[j]).isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
68 FuncDeclaration fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
69 TypeFunction tf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
70
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
71 //printf(" vtbl[%d] is '%s'\n", j, ifd ? ifd.toChars() : "null");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
72
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
73 assert(ifd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
74 // Find corresponding function in this class
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
75 tf = (ifd.type.ty == Tfunction) ? cast(TypeFunction)(ifd.type) : null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
76 fd = cd.findFunc(ifd.ident, tf);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
77 if (fd && !fd.isAbstract())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
78 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
79 //printf(" found\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
80 // Check that calling conventions match
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
81 if (fd.linkage != ifd.linkage)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
82 fd.error("linkage doesn't match interface function");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
83
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
84 // Check that it is current
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
85 if (newinstance &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
86 fd.toParent() != cd &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
87 ifd.toParent() == base
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
88 )
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
89 cd.error("interface function %s.%s is not implemented",
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
90 id.toChars(), ifd.ident.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
91
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
92 if (fd.toParent() == cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
93 result = true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
94 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
95 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
96 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
97 //printf(" not found\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
98 // BUG: should mark this class as abstract?
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
99 if (!cd.isAbstract())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
100 cd.error("interface function %s.%s isn't implemented", id.toChars(), ifd.ident.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
101 fd = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
102 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
103 if (vtbl)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
104 vtbl.data[j] = cast(void*)fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
105 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
106
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
107 return result;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
108 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
109
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
110 void copyBaseInterfaces(BaseClasses vtblInterfaces)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
111 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
112 //printf("+copyBaseInterfaces(), %s\n", base.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
113 // if (baseInterfaces_dim)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
114 // return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
115
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
116 baseInterfaces.length = base.interfaces_dim;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
117
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
118 int size = BaseClass.classinfo.init.length;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
119
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
120 //printf("%s.copyBaseInterfaces()\n", base.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
121 for (int i = 0; i < baseInterfaces.length; i++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
122 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
123 BaseClass b2 = base.interfaces[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
124 assert(b2.vtbl.dim == 0); // should not be filled yet
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
125
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
126 void* mem = malloc(size);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
127 memcpy(mem, cast(void*)b2, size);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
128
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
129 BaseClass b = cast(BaseClass)mem;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
130 baseInterfaces[i] = b;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
131
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
132 if (i) // single inheritance is i==0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
133 vtblInterfaces.push(cast(void*)b); // only need for M.I.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
134 b.copyBaseInterfaces(vtblInterfaces);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
135 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
136 //printf("-copyBaseInterfaces\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
137 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
138 }