Mercurial > projects > ddmd
annotate dmd/BaseClass.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
0 | 1 module dmd.BaseClass; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Type; |
5 import dmd.PROT; | |
6 import dmd.ClassDeclaration; | |
7 import dmd.Array; | |
8 import dmd.TY; | |
9 import dmd.TypeFunction; | |
10 import dmd.Dsymbol; | |
11 import dmd.FuncDeclaration; | |
12 import dmd.ArrayTypes; | |
178 | 13 import dmd.Util; |
0 | 14 |
15 import core.stdc.stdlib; | |
16 import core.stdc.string; | |
17 | |
4 | 18 import core.memory; |
2 | 19 |
178 | 20 import dmd.TObject; |
21 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
22 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
23 |
178 | 24 class BaseClass : TObject |
0 | 25 { |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
26 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
27 |
0 | 28 Type type; // (before semantic processing) |
29 PROT protection; // protection for the base interface | |
30 | |
31 ClassDeclaration base; | |
32 int offset; // 'this' pointer offset | |
33 Array vtbl; // for interfaces: Array of FuncDeclaration's | |
34 // making up the vtbl[] | |
35 | |
36 //int baseInterfaces_dim; | |
37 BaseClass[] baseInterfaces; // if BaseClass is an interface, these | |
38 // are a copy of the InterfaceDeclaration::interfaces | |
39 | |
40 this() | |
41 { | |
178 | 42 register(); |
43 | |
0 | 44 vtbl = new Array(); |
45 } | |
46 | |
47 this(Type type, PROT protection) | |
48 { | |
178 | 49 register(); |
50 | |
0 | 51 //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); |
52 this.type = type; | |
53 this.protection = protection; | |
178 | 54 |
0 | 55 vtbl = new Array(); |
56 } | |
57 | |
58 /**************************************** | |
59 * Fill in vtbl[] for base class based on member functions of class cd. | |
60 * Input: | |
61 * vtbl if !=null, fill it in | |
62 * newinstance !=0 means all entries must be filled in by members | |
63 * of cd, not members of any base classes of cd. | |
64 * Returns: | |
65 * true if any entries were filled in by members of cd (not exclusively | |
66 * by base classes) | |
67 */ | |
68 bool fillVtbl(ClassDeclaration cd, Array vtbl, int newinstance) | |
69 { | |
70 ClassDeclaration id = base; | |
71 int j; | |
72 bool result = false; | |
73 | |
74 //printf("BaseClass.fillVtbl(this='%s', cd='%s')\n", base.toChars(), cd.toChars()); | |
75 if (vtbl) | |
76 vtbl.setDim(base.vtbl.dim); | |
77 | |
78 // first entry is ClassInfo reference | |
79 for (j = base.vtblOffset(); j < base.vtbl.dim; j++) | |
80 { | |
81 FuncDeclaration ifd = (cast(Dsymbol)base.vtbl.data[j]).isFuncDeclaration(); | |
82 FuncDeclaration fd; | |
83 TypeFunction tf; | |
84 | |
85 //printf(" vtbl[%d] is '%s'\n", j, ifd ? ifd.toChars() : "null"); | |
86 | |
87 assert(ifd); | |
88 // Find corresponding function in this class | |
89 tf = (ifd.type.ty == Tfunction) ? cast(TypeFunction)(ifd.type) : null; | |
90 fd = cd.findFunc(ifd.ident, tf); | |
91 if (fd && !fd.isAbstract()) | |
92 { | |
93 //printf(" found\n"); | |
94 // Check that calling conventions match | |
95 if (fd.linkage != ifd.linkage) | |
96 fd.error("linkage doesn't match interface function"); | |
97 | |
98 // Check that it is current | |
99 if (newinstance && | |
100 fd.toParent() != cd && | |
101 ifd.toParent() == base | |
102 ) | |
103 cd.error("interface function %s.%s is not implemented", | |
104 id.toChars(), ifd.ident.toChars()); | |
105 | |
106 if (fd.toParent() == cd) | |
107 result = true; | |
108 } | |
109 else | |
110 { | |
111 //printf(" not found\n"); | |
112 // BUG: should mark this class as abstract? | |
113 if (!cd.isAbstract()) | |
114 cd.error("interface function %s.%s isn't implemented", id.toChars(), ifd.ident.toChars()); | |
115 fd = null; | |
116 } | |
117 if (vtbl) | |
118 vtbl.data[j] = cast(void*)fd; | |
119 } | |
120 | |
121 return result; | |
122 } | |
178 | 123 |
0 | 124 void copyBaseInterfaces(BaseClasses vtblInterfaces) |
125 { | |
126 //printf("+copyBaseInterfaces(), %s\n", base.toChars()); | |
127 // if (baseInterfaces_dim) | |
128 // return; | |
129 | |
130 baseInterfaces.length = base.interfaces_dim; | |
131 | |
132 //printf("%s.copyBaseInterfaces()\n", base.toChars()); | |
133 for (int i = 0; i < baseInterfaces.length; i++) | |
134 { | |
135 BaseClass b2 = base.interfaces[i]; | |
136 assert(b2.vtbl.dim == 0); // should not be filled yet | |
137 | |
178 | 138 BaseClass b = cloneThis(b2); |
0 | 139 baseInterfaces[i] = b; |
140 | |
141 if (i) // single inheritance is i==0 | |
125
767a01c2a272
BaseClasses -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
142 vtblInterfaces.push(b); // only need for M.I. |
0 | 143 b.copyBaseInterfaces(vtblInterfaces); |
144 } | |
145 //printf("-copyBaseInterfaces\n"); | |
146 } | |
178 | 147 } |