annotate gcc/d/dmd/dclass.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 /* Compiler implementation of the D programming language
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 * written by Walter Bright
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 * http://www.digitalmars.com
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 * Distributed under the Boost Software License, Version 1.0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 * http://www.boost.org/LICENSE_1_0.txt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/class.c
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 #include "root/dsystem.h" // mem{cpy|set}()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 #include "root/root.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 #include "root/rmem.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 #include "errors.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 #include "enum.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 #include "init.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "attrib.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "declaration.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "aggregate.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 #include "id.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "mtype.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "scope.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #include "module.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "expression.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "statement.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 #include "template.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 #include "target.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 #include "objc.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 bool symbolIsVisible(Dsymbol *origin, Dsymbol *s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 Objc *objc();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 /********************************* ClassDeclaration ****************************/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 ClassDeclaration *ClassDeclaration::object;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 ClassDeclaration *ClassDeclaration::throwable;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 ClassDeclaration *ClassDeclaration::exception;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 ClassDeclaration *ClassDeclaration::errorException;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 ClassDeclaration *ClassDeclaration::cpp_type_info_ptr; // Object.__cpp_type_info_ptr
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 : AggregateDeclaration(loc, id ? id : Identifier::generateId("__anonclass"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 static const char msg[] = "only object.d can define this reserved class name";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 if (baseclasses)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 // Actually, this is a transfer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 this->baseclasses = baseclasses;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 this->baseclasses = new BaseClasses();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 this->members = members;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 baseClass = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 interfaces.length = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 interfaces.ptr = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 vtblInterfaces = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 //printf("ClassDeclaration(%s), dim = %d\n", id->toChars(), this->baseclasses->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 // For forward references
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 type = new TypeClass(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 staticCtor = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 staticDtor = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 vtblsym = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 vclassinfo = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 if (id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 // Look for special class names
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 if (id == Id::__sizeof || id == Id::__xalignof || id == Id::_mangleof)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 error("illegal class name");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 // BUG: What if this is the wrong TypeInfo, i.e. it is nested?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 if (id->toChars()[0] == 'T')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 if (id == Id::TypeInfo)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 Type::dtypeinfo = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 if (id == Id::TypeInfo_Class)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 Type::typeinfoclass = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 if (id == Id::TypeInfo_Interface)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 Type::typeinfointerface = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 if (id == Id::TypeInfo_Struct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 Type::typeinfostruct = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 if (id == Id::TypeInfo_Pointer)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 Type::typeinfopointer = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 if (id == Id::TypeInfo_Array)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 Type::typeinfoarray = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 if (id == Id::TypeInfo_StaticArray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 //if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 // Type::typeinfostaticarray->error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 Type::typeinfostaticarray = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 if (id == Id::TypeInfo_AssociativeArray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 Type::typeinfoassociativearray = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 if (id == Id::TypeInfo_Enum)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 Type::typeinfoenum = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 if (id == Id::TypeInfo_Function)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 Type::typeinfofunction = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 if (id == Id::TypeInfo_Delegate)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 Type::typeinfodelegate = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 if (id == Id::TypeInfo_Tuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 Type::typeinfotypelist = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 if (id == Id::TypeInfo_Const)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 Type::typeinfoconst = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 if (id == Id::TypeInfo_Invariant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 Type::typeinfoinvariant = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 if (id == Id::TypeInfo_Shared)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 Type::typeinfoshared = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 if (id == Id::TypeInfo_Wild)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 Type::typeinfowild = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 if (id == Id::TypeInfo_Vector)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 Type::typeinfovector = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 if (id == Id::Object)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 object = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 if (id == Id::Throwable)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 throwable = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 if (id == Id::Exception)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 exception = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 if (id == Id::Error)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 errorException = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 if (id == Id::cpp_type_info_ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 if (!inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 error("%s", msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 cpp_type_info_ptr = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 com = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 cpp = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 isscope = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 isabstract = ABSfwdref;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 inuse = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 baseok = BASEOKnone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 isobjc = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 cpp_type_info_ptr_sym = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 ClassDeclaration *ClassDeclaration::create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 return new ClassDeclaration(loc, id, baseclasses, members, inObject);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 ClassDeclaration *cd =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 s ? (ClassDeclaration *)s
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 : new ClassDeclaration(loc, ident, NULL, NULL, false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 cd->storage_class |= storage_class;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 cd->baseclasses->setDim(this->baseclasses->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 for (size_t i = 0; i < cd->baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 BaseClass *b = (*this->baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 BaseClass *b2 = new BaseClass(b->type->syntaxCopy());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 (*cd->baseclasses)[i] = b2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 return ScopeDsymbol::syntaxCopy(cd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 Scope *ClassDeclaration::newScope(Scope *sc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 Scope *sc2 = AggregateDeclaration::newScope(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 if (isCOMclass())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 if (global.params.isWindows)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 sc2->linkage = LINKwindows;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 /* This enables us to use COM objects under Linux and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 * work with things like XPCOM
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 sc2->linkage = LINKc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 return sc2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 /* Bugzilla 12078, 12143 and 15733:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 * While resolving base classes and interfaces, a base may refer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 * the member of this derived class. In that time, if all bases of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 * this class can be determined, we can go forward the semantc process
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 * beyond the Lancestorsdone. To do the recursive semantic analysis,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 * temporarily set and unset `_scope` around exp().
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 static Type *resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, Type *type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 if (!scx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 scx = sc->copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 scx->setNoFree();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 cd->_scope = scx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 Type *t = type->semantic(cd->loc, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 cd->_scope = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 return t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 static void resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, ClassDeclaration *sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 if (!scx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 scx = sc->copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 scx->setNoFree();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 cd->_scope = scx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 sym->semantic(NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 cd->_scope = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 static void badObjectDotD(ClassDeclaration *cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 cd->error("missing or corrupt object.d");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 fatal();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 void ClassDeclaration::semantic(Scope *sc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : "");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 //printf("sc->stc = %x\n", sc->stc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 //{ static int n; if (++n == 20) *(char*)0=0; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 if (semanticRun >= PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 unsigned errors = global.errors;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 //printf("+ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 Scope *scx = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 if (_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 sc = _scope;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 scx = _scope; // save so we don't make redundant copies
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 _scope = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 if (!parent)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 assert(sc->parent);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 parent = sc->parent;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 if (this->errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 type = Type::terror;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 type = type->semantic(loc, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 if (ti && isError(ti))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 ((TypeClass *)type)->sym = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 // Ungag errors when not speculative
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 Ungag ungag = ungagSpeculative();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 if (semanticRun == PASSinit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 protection = sc->protection;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 storage_class |= sc->stc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 if (storage_class & STCdeprecated)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 isdeprecated = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 if (storage_class & STCauto)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 if (storage_class & STCscope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 isscope = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 if (storage_class & STCabstract)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 isabstract = ABSyes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 userAttribDecl = sc->userAttribDecl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 if (sc->linkage == LINKcpp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 cpp = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 if (sc->linkage == LINKobjc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 objc()->setObjc(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 else if (symtab && !scx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 semanticRun = PASSsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 semanticRun = PASSsemantic;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 if (baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 baseok = BASEOKin;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 // Expand any tuples in baseclasses[]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 for (size_t i = 0; i < baseclasses->dim; )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 b->type = resolveBase(this, sc, scx, b->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 Type *tb = b->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 if (tb->ty == Ttuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 TypeTuple *tup = (TypeTuple *)tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 baseclasses->remove(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 size_t dim = Parameter::dim(tup->arguments);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 for (size_t j = 0; j < dim; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 Parameter *arg = Parameter::getNth(tup->arguments, j);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 b = new BaseClass(arg->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 baseclasses->insert(i + j, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 i++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 if (baseok >= BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 if (semanticRun >= PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 goto Lancestorsdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 // See if there's a base class as first in baseclasses[]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 if (baseclasses->dim)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 BaseClass *b = (*baseclasses)[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 Type *tb = b->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 if (!tc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 if (b->type != Type::terror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 error("base type must be class or interface, not %s", b->type->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 baseclasses->remove(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 goto L7;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 if (tc->sym->isDeprecated())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 if (!isDeprecated())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 // Deriving from deprecated class makes this one deprecated too
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 isdeprecated = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 tc->checkDeprecated(loc, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 if (tc->sym->isInterfaceDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 goto L7;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 if (cdb == this)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 error("circular inheritance");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 baseclasses->remove(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 goto L7;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 /* Bugzilla 11034: Essentially, class inheritance hierarchy
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 * and instance size of each classes are orthogonal information.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 * Therefore, even if tc->sym->sizeof == SIZEOKnone,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 * we need to set baseClass field for class covariance check.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 baseClass = tc->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 b->sym = baseClass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 if (tc->sym->baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 if (tc->sym->baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 if (tc->sym->_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 baseok = BASEOKnone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 L7: ;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 // Treat the remaining entries in baseclasses as interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 // Check for errors, handle forward references
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 for (size_t i = (baseClass ? 1 : 0); i < baseclasses->dim; )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 Type *tb = b->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 if (!tc || !tc->sym->isInterfaceDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 if (b->type != Type::terror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 error("base type must be interface, not %s", b->type->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 baseclasses->remove(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 // Check for duplicate interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 for (size_t j = (baseClass ? 1 : 0); j < i; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 BaseClass *b2 = (*baseclasses)[j];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 if (b2->sym == tc->sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 error("inherits from duplicate interface %s", b2->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 baseclasses->remove(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 if (tc->sym->isDeprecated())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 if (!isDeprecated())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 // Deriving from deprecated class makes this one deprecated too
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 isdeprecated = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 tc->checkDeprecated(loc, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 b->sym = tc->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 if (tc->sym->baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 if (tc->sym->baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 if (tc->sym->_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 baseok = BASEOKnone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 i++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 if (baseok == BASEOKnone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 // Forward referencee of one or more bases, try again later
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 _scope = scx ? scx : sc->copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 _scope->setNoFree();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 _scope->_module->addDeferredSemantic(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 baseok = BASEOKdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 // If no base class, and this is not an Object, use Object as base class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 if (!baseClass && ident != Id::Object && !cpp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 if (!object || object->errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 badObjectDotD(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 Type *t = object->type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 t = t->semantic(loc, sc)->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 if (t->ty == Terror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 badObjectDotD(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 assert(t->ty == Tclass);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 TypeClass *tc = (TypeClass *)t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 BaseClass *b = new BaseClass(tc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 baseclasses->shift(b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 baseClass = tc->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 assert(!baseClass->isInterfaceDeclaration());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 b->sym = baseClass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 if (baseClass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 if (baseClass->storage_class & STCfinal)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 error("cannot inherit from final class %s", baseClass->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 // Inherit properties from base class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 if (baseClass->isCOMclass())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 com = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 if (baseClass->isCPPclass())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 cpp = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 if (baseClass->isscope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 isscope = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 enclosing = baseClass->enclosing;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 storage_class |= baseClass->storage_class & STC_TYPECTOR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 interfaces.length = baseclasses->dim - (baseClass ? 1 : 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 interfaces.ptr = baseclasses->tdata() + (baseClass ? 1 : 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 for (size_t i = 0; i < interfaces.length; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 BaseClass *b = interfaces.ptr[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 // If this is an interface, and it derives from a COM interface,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 // then this is a COM interface too.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 if (b->sym->isCOMinterface())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 com = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 if (cpp && !b->sym->isCPPinterface())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 ::error(loc, "C++ class '%s' cannot implement D interface '%s'",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 toPrettyChars(), b->sym->toPrettyChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 interfaceSemantic(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 Lancestorsdone:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 //printf("\tClassDeclaration::semantic(%s) baseok = %d\n", toChars(), baseok);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 if (!members) // if opaque declaration
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 semanticRun = PASSsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 if (!symtab)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 symtab = new DsymbolTable();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 /* Bugzilla 12152: The semantic analysis of base classes should be finished
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 * before the members semantic analysis of this class, in order to determine
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 * vtbl in this class. However if a base class refers the member of this class,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 * it can be resolved as a normal forward reference.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 * Call addMember() and setScope() to make this class members visible from the base classes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 s->addMember(sc, this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 Scope *sc2 = newScope(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 /* Set scope so if there are forward references, we still might be able to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 * resolve individual members like enums.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 //printf("[%d] setScope %s %s, sc2 = %p\n", i, s->kind(), s->toChars(), sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 s->setScope(sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 sc2->pop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 for (size_t i = 0; i < baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 Type *tb = b->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 assert(tb->ty == Tclass);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 TypeClass *tc = (TypeClass *)tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 if (tc->sym->semanticRun < PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 // Forward referencee of one or more bases, try again later
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 _scope = scx ? scx : sc->copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 _scope->setNoFree();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 if (tc->sym->_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 _scope->_module->addDeferredSemantic(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 if (baseok == BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 baseok = BASEOKsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 // initialize vtbl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 if (baseClass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 if (cpp && baseClass->vtbl.dim == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 error("C++ base class %s needs at least one virtual function", baseClass->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 // Copy vtbl[] from base class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 vtbl.setDim(baseClass->vtbl.dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 vthis = baseClass->vthis;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 // No base class, so this is the root of the class hierarchy
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 vtbl.setDim(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 if (vtblOffset())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 vtbl.push(this); // leave room for classinfo as first member
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 /* If this is a nested class, add the hidden 'this'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 * member which is a pointer to the enclosing scope.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 if (vthis) // if inheriting from nested class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 // Use the base class's 'this' member
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 if (storage_class & STCstatic)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 error("static class cannot inherit from nested class %s", baseClass->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 if (toParent2() != baseClass->toParent2() &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 (!toParent2() ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 !baseClass->toParent2()->getType() ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 !baseClass->toParent2()->getType()->isBaseOf(toParent2()->getType(), NULL)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 if (toParent2())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 error("is nested within %s, but super class %s is nested within %s",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 toParent2()->toChars(),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 baseClass->toChars(),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 baseClass->toParent2()->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 error("is not nested, but super class %s is nested within %s",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 baseClass->toChars(),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 baseClass->toParent2()->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 enclosing = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 makeNested();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 Scope *sc2 = newScope(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 s->importAll(sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 // Note that members.dim can grow due to tuple expansion during semantic()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 s->semantic(sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 if (!determineFields())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 assert(type == Type::terror);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 sc2->pop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 /* Following special member functions creation needs semantic analysis
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 * completion of sub-structs in each field types.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 for (size_t i = 0; i < fields.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758 VarDeclaration *v = fields[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 Type *tb = v->type->baseElemOf();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 if (tb->ty != Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 if (sd->semanticRun >= PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 sc2->pop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 _scope = scx ? scx : sc->copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 _scope->setNoFree();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 _scope->_module->addDeferredSemantic(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 //printf("\tdeferring %s\n", toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 /* Look for special member functions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 * They must be in this class, not in a base class.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 // Can be in base class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 aggNew = (NewDeclaration *)search(Loc(), Id::classNew);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 // Look for the constructor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 ctor = searchCtor();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 if (!ctor && noDefaultCtor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 // A class object is always created by constructor, so this check is legitimate.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 for (size_t i = 0; i < fields.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 VarDeclaration *v = fields[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 if (v->storage_class & STCnodefaultctor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 ::error(v->loc, "field %s must be initialized in constructor", v->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 // If this class has no constructor, but base class has a default
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 // ctor, create a constructor:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 // this() { }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 if (!ctor && baseClass && baseClass->ctor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 FuncDeclaration *fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type, NULL, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 if (!fd) // try shared base ctor instead
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type->sharedOf(), NULL, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 if (fd && !fd->errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 //printf("Creating default this(){} for class %s\n", toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 TypeFunction *btf = fd->type->toTypeFunction();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 TypeFunction *tf = new TypeFunction(NULL, NULL, 0, LINKd, fd->storage_class);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 tf->mod = btf->mod;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 tf->purity = btf->purity;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 tf->isnothrow = btf->isnothrow;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 tf->isnogc = btf->isnogc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 tf->trust = btf->trust;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 CtorDeclaration *ctor = new CtorDeclaration(loc, Loc(), 0, tf);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 ctor->fbody = new CompoundStatement(Loc(), new Statements());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 members->push(ctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 ctor->addMember(sc, this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 ctor->semantic(sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 this->ctor = ctor;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 defaultCtor = ctor;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 error("cannot implicitly generate a default ctor when base class %s is missing a default ctor",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 baseClass->toPrettyChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 dtor = buildDtor(this, sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 if (FuncDeclaration *f = hasIdentityOpAssign(this, sc2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 if (!(f->storage_class & STCdisable))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 error(f->loc, "identity assignment operator overload is illegal");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 inv = buildInv(this, sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 Module::dprogress++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 semanticRun = PASSsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 //members.print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 sc2->pop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852 // https://issues.dlang.org/show_bug.cgi?id=17492
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 ClassDeclaration *cd = ((TypeClass *)type)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 error("already exists at %s. Perhaps in another function with the same name?", cd->loc.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 if (global.errors != errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 // The type is no good.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 type = Type::terror;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 this->errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 if (deferred)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 deferred->errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866 // Verify fields of a synchronized class are not public
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 if (storage_class & STCsynchronized)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 for (size_t i = 0; i < fields.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 VarDeclaration *vd = fields[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 if (!vd->isThisDeclaration() &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 !vd->prot().isMoreRestrictiveThan(Prot(PROTpublic)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 vd->error("Field members of a synchronized class cannot be %s",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 protectionToChars(vd->prot().kind));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 if (deferred && !global.gag)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 deferred->semantic2(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 deferred->semantic3(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 //printf("-ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 /*********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 * Determine if 'this' is a base class of cd.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 * This is used to detect circular inheritance only.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 bool ClassDeclaration::isBaseOf2(ClassDeclaration *cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 if (!cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 for (size_t i = 0; i < cd->baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 BaseClass *b = (*cd->baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 if (b->sym == this || isBaseOf2(b->sym))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 /*******************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 * Determine if 'this' is a base class of cd.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 bool ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 if (poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 *poffset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 while (cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 /* cd->baseClass might not be set if cd is forward referenced.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921 if (!cd->baseClass && cd->semanticRun < PASSsemanticdone && !cd->isInterfaceDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923 cd->semantic(NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 if (!cd->baseClass && cd->semanticRun < PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925 cd->error("base class is forward referenced by %s", toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 if (this == cd->baseClass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931 cd = cd->baseClass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 /*********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 * Determine if 'this' has complete base class information.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 * This is used to detect forward references in covariant overloads.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 bool ClassDeclaration::isBaseInfoComplete()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943 return baseok >= BASEOKdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 Dsymbol *ClassDeclaration::search(const Loc &loc, Identifier *ident, int flags)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 //printf("%s.ClassDeclaration::search('%s', flags=x%x)\n", toChars(), ident->toChars(), flags);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 //if (_scope) printf("%s baseok = %d\n", toChars(), baseok);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951 if (_scope && baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953 if (!inuse)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 // must semantic on base class/interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 ++inuse;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 semantic(NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 --inuse;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 if (!members || !symtab) // opaque or addMember is not yet done
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 error("is forward referenced when looking for '%s'", ident->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965 //*(char*)0=0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 Dsymbol *s = ScopeDsymbol::search(loc, ident, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 // don't search imports of base classes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972 if (flags & SearchImportsOnly)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 return s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 if (!s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 // Search bases classes in depth-first, left to right order
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 for (size_t i = 0; i < baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 if (b->sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 if (!b->sym->symtab)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 error("base %s is forward referenced", b->sym->ident->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 s = b->sym->search(loc, ident, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 if (!s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 else if (s == this) // happens if s is nested in this and derives from this
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 s = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994 else if (!(flags & IgnoreSymbolVisibility) && !(s->prot().kind == PROTprotected) && !symbolIsVisible(this, s))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 s = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 return s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 /************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 * Search base classes in depth-first, left-to-right order for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 * a class or interface named 'ident'.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008 * Stops at first found. Does not look for additional matches.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 * ident = identifier to search for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012 * ClassDeclaration if found, null if not
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 ClassDeclaration *ClassDeclaration::searchBase(Identifier *ident)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016 for (size_t i = 0; i < baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019 ClassDeclaration *cdb = b->type->isClassHandle();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 if (!cdb) // Bugzilla 10616
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022 if (cdb->ident->equals(ident))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023 return cdb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024 cdb = cdb->searchBase(ident);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 if (cdb)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026 return cdb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031 /****
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032 * Runs through the inheritance graph to set the BaseClass.offset fields.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033 * Recursive in order to account for the size of the interface classes, if they are
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 * more than just interfaces.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036 * cd = interface to look at
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037 * baseOffset = offset of where cd will be placed
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 * subset of instantiated size used by cd for interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041 static unsigned membersPlace(BaseClasses *vtblInterfaces, size_t &bi, ClassDeclaration *cd, unsigned baseOffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043 //printf(" membersPlace(%s, %d)\n", cd->toChars(), baseOffset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 unsigned offset = baseOffset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046 for (size_t i = 0; i < cd->interfaces.length; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048 BaseClass *b = cd->interfaces.ptr[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049 if (b->sym->sizeok != SIZEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050 b->sym->finalizeSize();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051 assert(b->sym->sizeok == SIZEOKdone);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053 if (!b->sym->alignsize)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054 b->sym->alignsize = Target::ptrsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055 cd->alignmember(b->sym->alignsize, b->sym->alignsize, &offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056 assert(bi < vtblInterfaces->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057 BaseClass *bv = (*vtblInterfaces)[bi];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 if (b->sym->interfaces.length == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060 //printf("\tvtblInterfaces[%d] b=%p b->sym = %s, offset = %d\n", bi, bv, bv->sym->toChars(), offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 bv->offset = offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062 ++bi;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063 // All the base interfaces down the left side share the same offset
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064 for (BaseClass *b2 = bv; b2->baseInterfaces.length; )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 b2 = &b2->baseInterfaces.ptr[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067 b2->offset = offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068 //printf("\tvtblInterfaces[%d] b=%p sym = %s, offset = %d\n", bi, b2, b2->sym->toChars(), b2->offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 membersPlace(vtblInterfaces, bi, b->sym, offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 //printf(" %s size = %d\n", b->sym->toChars(), b->sym->structsize);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 offset += b->sym->structsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074 if (cd->alignsize < b->sym->alignsize)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075 cd->alignsize = b->sym->alignsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077 return offset - baseOffset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 void ClassDeclaration::finalizeSize()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 assert(sizeok != SIZEOKdone);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 // Set the offsets of the fields and determine the size of the class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 if (baseClass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087 assert(baseClass->sizeok == SIZEOKdone);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 alignsize = baseClass->alignsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 structsize = baseClass->structsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091 if (cpp && global.params.isWindows)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094 else if (isInterfaceDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096 if (interfaces.length == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098 alignsize = Target::ptrsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099 structsize = Target::ptrsize; // allow room for __vptr
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 alignsize = Target::ptrsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105 structsize = Target::ptrsize; // allow room for __vptr
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106 if (!cpp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107 structsize += Target::ptrsize; // allow room for __monitor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 //printf("finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111 size_t bi = 0; // index into vtblInterfaces[]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 // Add vptr's for any interfaces implemented by this class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114 structsize += membersPlace(vtblInterfaces, bi, this, structsize);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116 if (isInterfaceDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1118 sizeok = SIZEOKdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1119 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1120 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1122 // FIXME: Currently setFieldOffset functions need to increase fields
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1123 // to calculate each variable offsets. It can be improved later.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1124 fields.setDim(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1125
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1126 unsigned offset = structsize;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1127 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1128 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1129 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1130 s->setFieldOffset(this, &offset, false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1131 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1132
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1133 sizeok = SIZEOKdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1134
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1135 // Calculate fields[i]->overlapped
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1136 checkOverlappedFields();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1137 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1139 /**********************************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1140 * fd is in the vtbl[] for this class.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1141 * Return 1 if function is hidden (not findable through search).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1142 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1143
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1144 int isf(void *param, Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1145 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1146 FuncDeclaration *fd = s->isFuncDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1147 if (!fd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1148 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1149 //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1150 return (RootObject *)param == fd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1151 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1152
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1153 bool ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1154 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1155 //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toPrettyChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1156 Dsymbol *s = search(Loc(), fd->ident, IgnoreAmbiguous | IgnoreErrors);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1157 if (!s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1158 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1159 //printf("not found\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1160 /* Because, due to a hack, if there are multiple definitions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1161 * of fd->ident, NULL is returned.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1162 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1163 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1164 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1165 s = s->toAlias();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1166 OverloadSet *os = s->isOverloadSet();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1167 if (os)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1168 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1169 for (size_t i = 0; i < os->a.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1170 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1171 Dsymbol *s2 = os->a[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1172 FuncDeclaration *f2 = s2->isFuncDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1173 if (f2 && overloadApply(f2, (void *)fd, &isf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1174 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1175 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1176 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1177 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1178 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1179 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1180 FuncDeclaration *fdstart = s->isFuncDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1181 //printf("%s fdstart = %p\n", s->kind(), fdstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1182 if (overloadApply(fdstart, (void *)fd, &isf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1183 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1184
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1185 return !fd->parent->isTemplateMixin();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1186 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1187 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1188
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1189 /****************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1190 * Find virtual function matching identifier and type.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1191 * Used to build virtual function tables for interface implementations.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1192 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1193
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1194 FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1195 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1196 //printf("ClassDeclaration::findFunc(%s, %s) %s\n", ident->toChars(), tf->toChars(), toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1197 FuncDeclaration *fdmatch = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1198 FuncDeclaration *fdambig = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1199
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1200 ClassDeclaration *cd = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1201 Dsymbols *vtbl = &cd->vtbl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1202 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1203 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1204 for (size_t i = 0; i < vtbl->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1205 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1206 FuncDeclaration *fd = (*vtbl)[i]->isFuncDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1207 if (!fd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1208 continue; // the first entry might be a ClassInfo
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1210 //printf("\t[%d] = %s\n", i, fd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1211 if (ident == fd->ident &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1212 fd->type->covariant(tf) == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1213 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1214 //printf("fd->parent->isClassDeclaration() = %p\n", fd->parent->isClassDeclaration());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1215 if (!fdmatch)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1216 goto Lfd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1217 if (fd == fdmatch)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1218 goto Lfdmatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1220 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1221 // Function type matcing: exact > covariant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1222 MATCH m1 = tf->equals(fd ->type) ? MATCHexact : MATCHnomatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1223 MATCH m2 = tf->equals(fdmatch->type) ? MATCHexact : MATCHnomatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1224 if (m1 > m2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1225 goto Lfd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1226 else if (m1 < m2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1227 goto Lfdmatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1228 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1230 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1231 MATCH m1 = (tf->mod == fd ->type->mod) ? MATCHexact : MATCHnomatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1232 MATCH m2 = (tf->mod == fdmatch->type->mod) ? MATCHexact : MATCHnomatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1233 if (m1 > m2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1234 goto Lfd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1235 else if (m1 < m2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1236 goto Lfdmatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1237 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1238
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1239 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1240 // The way of definition: non-mixin > mixin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1241 MATCH m1 = fd ->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1242 MATCH m2 = fdmatch->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1243 if (m1 > m2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1244 goto Lfd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1245 else if (m1 < m2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1246 goto Lfdmatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1247 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1248
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1249 fdambig = fd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1250 //printf("Lambig fdambig = %s %s [%s]\n", fdambig->toChars(), fdambig->type->toChars(), fdambig->loc.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1251 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1252
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1253 Lfd:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1254 fdmatch = fd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1255 fdambig = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1256 //printf("Lfd fdmatch = %s %s [%s]\n", fdmatch->toChars(), fdmatch->type->toChars(), fdmatch->loc.toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1257 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1258
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1259 Lfdmatch:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1260 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1261 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1262 //else printf("\t\t%d\n", fd->type->covariant(tf));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1263 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1264 if (!cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1265 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1266 vtbl = &cd->vtblFinal;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1267 cd = cd->baseClass;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1268 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1269
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1270 if (fdambig)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1271 error("ambiguous virtual function %s", fdambig->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1272 return fdmatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1273 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1274
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1275 void ClassDeclaration::interfaceSemantic(Scope *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1276 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1277 vtblInterfaces = new BaseClasses();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1278 vtblInterfaces->reserve(interfaces.length);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1279
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1280 for (size_t i = 0; i < interfaces.length; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1281 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1282 BaseClass *b = interfaces.ptr[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1283 vtblInterfaces->push(b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1284 b->copyBaseInterfaces(vtblInterfaces);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1285 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1286 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1287
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1288 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1289 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1290
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1291 bool ClassDeclaration::isCOMclass() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1292 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1293 return com;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1294 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1295
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1296 bool ClassDeclaration::isCOMinterface() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1297 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1298 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1299 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1300
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1301 bool ClassDeclaration::isCPPclass() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1302 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1303 return cpp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1304 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1305
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1306 bool ClassDeclaration::isCPPinterface() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1307 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1308 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1309 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1310
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1311
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1312 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1313 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1314
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1315 bool ClassDeclaration::isAbstract()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1316 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1317 if (isabstract != ABSfwdref)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1318 return isabstract == ABSyes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1319
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1320 /* Bugzilla 11169: Resolve forward references to all class member functions,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1321 * and determine whether this class is abstract.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1322 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1323 struct SearchAbstract
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1324 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1325 static int fp(Dsymbol *s, void *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1326 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1327 FuncDeclaration *fd = s->isFuncDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1328 if (!fd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1329 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1330 if (fd->storage_class & STCstatic)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1331 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1332
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1333 if (fd->_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1334 fd->semantic(NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1335
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1336 if (fd->isAbstract())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1337 return 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1338 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1339 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1340 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1341
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1342 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1343 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1344 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1345 if (s->apply(&SearchAbstract::fp, this))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1346 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1347 isabstract = ABSyes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1348 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1349 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1350 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1351
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1352 /* Iterate inherited member functions and check their abstract attribute.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1353 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1354 for (size_t i = 1; i < vtbl.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1355 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1356 FuncDeclaration *fd = vtbl[i]->isFuncDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1357 //if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd->loc.toChars(), fd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1358 if (!fd || fd->isAbstract())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1359 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1360 isabstract = ABSyes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1361 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1362 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1363 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1364
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1365 isabstract = ABSno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1366 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1367 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1368
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1369
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1370 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1371 * Determine if slot 0 of the vtbl[] is reserved for something else.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1372 * For class objects, yes, this is where the classinfo ptr goes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1373 * For COM interfaces, no.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1374 * For non-COM interfaces, yes, this is where the Interface ptr goes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1375 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1376 * 0 vtbl[0] is first virtual function pointer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1377 * 1 vtbl[0] is classinfo/interfaceinfo pointer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1378 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1379
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1380 int ClassDeclaration::vtblOffset() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1381 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1382 return cpp ? 0 : 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1383 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1384
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1385 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1386 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1387
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1388 const char *ClassDeclaration::kind() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1389 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1390 return "class";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1391 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1392
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1393 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1394 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1395
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1396 void ClassDeclaration::addLocalClass(ClassDeclarations *aclasses)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1397 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1398 aclasses->push(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1399 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1400
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1401 /********************************* InterfaceDeclaration ****************************/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1402
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1403 InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1404 : ClassDeclaration(loc, id, baseclasses, NULL, false)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1405 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1406 if (id == Id::IUnknown) // IUnknown is the root of all COM interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1407 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1408 com = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1409 cpp = true; // IUnknown is also a C++ interface
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1410 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1411 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1412
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1413 Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1414 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1415 InterfaceDeclaration *id =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1416 s ? (InterfaceDeclaration *)s
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1417 : new InterfaceDeclaration(loc, ident, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1418 return ClassDeclaration::syntaxCopy(id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1419 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1420
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1421 Scope *InterfaceDeclaration::newScope(Scope *sc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1422 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1423 Scope *sc2 = ClassDeclaration::newScope(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1424 if (com)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1425 sc2->linkage = LINKwindows;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1426 else if (cpp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1427 sc2->linkage = LINKcpp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1428 else if (isobjc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1429 sc2->linkage = LINKobjc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1430 return sc2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1431 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1432
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1433 void InterfaceDeclaration::semantic(Scope *sc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1434 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1435 //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1436 if (semanticRun >= PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1437 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1438 unsigned errors = global.errors;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1439
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1440 //printf("+InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1441
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1442 Scope *scx = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1443 if (_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1444 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1445 sc = _scope;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1446 scx = _scope; // save so we don't make redundant copies
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1447 _scope = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1448 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1449
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1450 if (!parent)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1451 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1452 assert(sc->parent && sc->func);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1453 parent = sc->parent;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1454 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1455 assert(parent && !isAnonymous());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1456
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1457 if (this->errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1458 type = Type::terror;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1459 type = type->semantic(loc, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1460
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1461 if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1462 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1463 TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1464 if (ti && isError(ti))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1465 ((TypeClass *)type)->sym = this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1466 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1467
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1468 // Ungag errors when not speculative
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1469 Ungag ungag = ungagSpeculative();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1470
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1471 if (semanticRun == PASSinit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1472 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1473 protection = sc->protection;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1474
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1475 storage_class |= sc->stc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1476 if (storage_class & STCdeprecated)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1477 isdeprecated = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1478
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1479 userAttribDecl = sc->userAttribDecl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1480 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1481 else if (symtab)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1482 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1483 if (sizeok == SIZEOKdone || !scx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1484 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1485 semanticRun = PASSsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1486 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1487 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1488 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1489 semanticRun = PASSsemantic;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1490
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1491 if (baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1492 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1493 baseok = BASEOKin;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1494
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1495 // Expand any tuples in baseclasses[]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1496 for (size_t i = 0; i < baseclasses->dim; )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1497 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1498 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1499 b->type = resolveBase(this, sc, scx, b->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1500
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1501 Type *tb = b->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1502 if (tb->ty == Ttuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1503 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1504 TypeTuple *tup = (TypeTuple *)tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1505 baseclasses->remove(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1506 size_t dim = Parameter::dim(tup->arguments);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1507 for (size_t j = 0; j < dim; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1508 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1509 Parameter *arg = Parameter::getNth(tup->arguments, j);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1510 b = new BaseClass(arg->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1511 baseclasses->insert(i + j, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1512 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1513 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1514 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1515 i++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1516 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1517
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1518 if (baseok >= BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1519 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1520 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1521 if (semanticRun >= PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1522 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1523 goto Lancestorsdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1524 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1525
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1526 if (!baseclasses->dim && sc->linkage == LINKcpp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1527 cpp = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1528 if (sc->linkage == LINKobjc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1529 objc()->setObjc(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1530
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1531 // Check for errors, handle forward references
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1532 for (size_t i = 0; i < baseclasses->dim; )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1533 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1534 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1535 Type *tb = b->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1536 TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1537 if (!tc || !tc->sym->isInterfaceDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1538 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1539 if (b->type != Type::terror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1540 error("base type must be interface, not %s", b->type->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1541 baseclasses->remove(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1542 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1543 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1544
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1545 // Check for duplicate interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1546 for (size_t j = 0; j < i; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1547 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1548 BaseClass *b2 = (*baseclasses)[j];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1549 if (b2->sym == tc->sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1550 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1551 error("inherits from duplicate interface %s", b2->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1552 baseclasses->remove(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1553 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1554 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1555 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1556
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1557 if (tc->sym == this || isBaseOf2(tc->sym))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1558 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1559 error("circular inheritance of interface");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1560 baseclasses->remove(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1561 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1562 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1563
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1564 if (tc->sym->isDeprecated())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1565 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1566 if (!isDeprecated())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1567 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1568 // Deriving from deprecated class makes this one deprecated too
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1569 isdeprecated = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1570
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1571 tc->checkDeprecated(loc, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1572 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1573 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1574
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1575 b->sym = tc->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1576
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1577 if (tc->sym->baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1578 resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1579 if (tc->sym->baseok < BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1580 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1581 //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1582 if (tc->sym->_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1583 tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1584 baseok = BASEOKnone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1585 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1586 i++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1587 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1588 if (baseok == BASEOKnone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1589 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1590 // Forward referencee of one or more bases, try again later
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1591 _scope = scx ? scx : sc->copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1592 _scope->setNoFree();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1593 _scope->_module->addDeferredSemantic(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1594 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1595 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1596 baseok = BASEOKdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1597
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1598 interfaces.length = baseclasses->dim;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1599 interfaces.ptr = baseclasses->tdata();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1600
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1601 for (size_t i = 0; i < interfaces.length; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1602 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1603 BaseClass *b = interfaces.ptr[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1604 // If this is an interface, and it derives from a COM interface,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1605 // then this is a COM interface too.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1606 if (b->sym->isCOMinterface())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1607 com = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1608 if (b->sym->isCPPinterface())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1609 cpp = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1610 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1611
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1612 interfaceSemantic(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1613 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1614 Lancestorsdone:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1615
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1616 if (!members) // if opaque declaration
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1617 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1618 semanticRun = PASSsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1619 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1620 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1621 if (!symtab)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1622 symtab = new DsymbolTable();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1623
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1624 for (size_t i = 0; i < baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1625 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1626 BaseClass *b = (*baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1627 Type *tb = b->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1628 assert(tb->ty == Tclass);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1629 TypeClass *tc = (TypeClass *)tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1630
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1631 if (tc->sym->semanticRun < PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1632 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1633 // Forward referencee of one or more bases, try again later
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1634 _scope = scx ? scx : sc->copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1635 _scope->setNoFree();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1636 if (tc->sym->_scope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1637 tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1638 _scope->_module->addDeferredSemantic(this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1639 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1640 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1641 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1642
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1643 if (baseok == BASEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1644 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1645 baseok = BASEOKsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1646
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1647 // initialize vtbl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1648 if (vtblOffset())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1649 vtbl.push(this); // leave room at vtbl[0] for classinfo
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1650
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1651 // Cat together the vtbl[]'s from base interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1652 for (size_t i = 0; i < interfaces.length; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1653 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1654 BaseClass *b = interfaces.ptr[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1655
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1656 // Skip if b has already appeared
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1657 for (size_t k = 0; k < i; k++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1658 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1659 if (b == interfaces.ptr[k])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1660 goto Lcontinue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1661 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1662
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1663 // Copy vtbl[] from base class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1664 if (b->sym->vtblOffset())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1665 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1666 size_t d = b->sym->vtbl.dim;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1667 if (d > 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1668 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1669 vtbl.reserve(d - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1670 for (size_t j = 1; j < d; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1671 vtbl.push(b->sym->vtbl[j]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1672 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1673 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1674 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1675 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1676 vtbl.append(&b->sym->vtbl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1677 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1678
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1679 Lcontinue:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1680 ;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1681 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1682 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1683
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1684 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1685 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1686 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1687 s->addMember(sc, this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1688 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1689
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1690 Scope *sc2 = newScope(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1691
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1692 /* Set scope so if there are forward references, we still might be able to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1693 * resolve individual members like enums.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1694 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1695 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1696 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1697 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1698 //printf("setScope %s %s\n", s->kind(), s->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1699 s->setScope(sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1700 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1701
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1702 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1703 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1704 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1705 s->importAll(sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1706 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1707
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1708 for (size_t i = 0; i < members->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1709 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1710 Dsymbol *s = (*members)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1711 s->semantic(sc2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1712 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1713
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1714 Module::dprogress++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1715 semanticRun = PASSsemanticdone;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1716 //printf("-InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1717 //members->print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1718
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1719 sc2->pop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1720
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1721 if (global.errors != errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1722 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1723 // The type is no good.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1724 type = Type::terror;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1725 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1726
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1727 assert(type->ty != Tclass || ((TypeClass *)type)->sym == this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1728 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1729
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1730 /*******************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1731 * Determine if 'this' is a base class of cd.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1732 * (Actually, if it is an interface supported by cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1733 * Output:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1734 * *poffset offset to start of class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1735 * OFFSET_RUNTIME must determine offset at runtime
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1736 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1737 * false not a base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1738 * true is a base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1739 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1740
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1741 bool InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1742 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1743 //printf("%s.InterfaceDeclaration::isBaseOf(cd = '%s')\n", toChars(), cd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1744 assert(!baseClass);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1745 for (size_t j = 0; j < cd->interfaces.length; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1746 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1747 BaseClass *b = cd->interfaces.ptr[j];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1748
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1749 //printf("\tX base %s\n", b->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1750 if (this == b->sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1751 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1752 //printf("\tfound at offset %d\n", b->offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1753 if (poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1754 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1755 // don't return incorrect offsets https://issues.dlang.org/show_bug.cgi?id=16980
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1756 *poffset = cd->sizeok == SIZEOKdone ? b->offset : OFFSET_FWDREF;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1757 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1758 //printf("\tfound at offset %d\n", b->offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1759 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1760 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1761 if (isBaseOf(b, poffset))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1762 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1763 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1764
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1765 if (cd->baseClass && isBaseOf(cd->baseClass, poffset))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1766 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1767
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1768 if (poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1769 *poffset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1770 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1771 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1772
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1773 bool InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1774 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1775 //printf("%s.InterfaceDeclaration::isBaseOf(bc = '%s')\n", toChars(), bc->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1776 for (size_t j = 0; j < bc->baseInterfaces.length; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1777 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1778 BaseClass *b = &bc->baseInterfaces.ptr[j];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1779
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1780 //printf("\tY base %s\n", b->sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1781 if (this == b->sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1782 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1783 //printf("\tfound at offset %d\n", b->offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1784 if (poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1785 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1786 *poffset = b->offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1787 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1788 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1789 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1790 if (isBaseOf(b, poffset))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1791 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1792 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1793 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1794 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1795 if (poffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1796 *poffset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1797 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1798 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1799
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1800 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1801 * Determine if slot 0 of the vtbl[] is reserved for something else.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1802 * For class objects, yes, this is where the ClassInfo ptr goes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1803 * For COM interfaces, no.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1804 * For non-COM interfaces, yes, this is where the Interface ptr goes.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1805 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1806
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1807 int InterfaceDeclaration::vtblOffset() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1808 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1809 if (isCOMinterface() || isCPPinterface())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1810 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1811 return 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1812 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1813
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1814 bool InterfaceDeclaration::isCOMinterface() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1815 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1816 return com;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1817 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1818
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1819 bool InterfaceDeclaration::isCPPinterface() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1820 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1821 return cpp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1822 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1823
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1824 /*******************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1825 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1826
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1827 const char *InterfaceDeclaration::kind() const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1828 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1829 return "interface";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1830 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1831
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1832
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1833 /******************************** BaseClass *****************************/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1834
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1835 BaseClass::BaseClass()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1836 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1837 this->type = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1838 this->sym = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1839 this->offset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1840
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1841 this->baseInterfaces.length = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1842 this->baseInterfaces.ptr = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1843 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1844
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1845 BaseClass::BaseClass(Type *type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1846 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1847 //printf("BaseClass(this = %p, '%s')\n", this, type->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1848 this->type = type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1849 this->sym = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1850 this->offset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1851
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1852 this->baseInterfaces.length = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1853 this->baseInterfaces.ptr = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1854 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1855
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1856 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1857 * Fill in vtbl[] for base class based on member functions of class cd.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1858 * Input:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1859 * vtbl if !=NULL, fill it in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1860 * newinstance !=0 means all entries must be filled in by members
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1861 * of cd, not members of any base classes of cd.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1862 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1863 * true if any entries were filled in by members of cd (not exclusively
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1864 * by base classes)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1865 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1866
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1867 bool BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1868 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1869 bool result = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1870
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1871 //printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", sym->toChars(), cd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1872 if (vtbl)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1873 vtbl->setDim(sym->vtbl.dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1874
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1875 // first entry is ClassInfo reference
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1876 for (size_t j = sym->vtblOffset(); j < sym->vtbl.dim; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1877 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1878 FuncDeclaration *ifd = sym->vtbl[j]->isFuncDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1879 FuncDeclaration *fd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1880 TypeFunction *tf;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1881
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1882 //printf(" vtbl[%d] is '%s'\n", j, ifd ? ifd->toChars() : "null");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1883
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1884 assert(ifd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1885 // Find corresponding function in this class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1886 tf = ifd->type->toTypeFunction();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1887 fd = cd->findFunc(ifd->ident, tf);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1888 if (fd && !fd->isAbstract())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1889 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1890 //printf(" found\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1891 // Check that calling conventions match
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1892 if (fd->linkage != ifd->linkage)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1893 fd->error("linkage doesn't match interface function");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1894
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1895 // Check that it is current
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1896 //printf("newinstance = %d fd->toParent() = %s ifd->toParent() = %s\n",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1897 //newinstance, fd->toParent()->toChars(), ifd->toParent()->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1898 if (newinstance && fd->toParent() != cd && ifd->toParent() == sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1899 cd->error("interface function '%s' is not implemented", ifd->toFullSignature());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1900
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1901 if (fd->toParent() == cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1902 result = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1903 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1904 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1905 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1906 //printf(" not found %p\n", fd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1907 // BUG: should mark this class as abstract?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1908 if (!cd->isAbstract())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1909 cd->error("interface function '%s' is not implemented", ifd->toFullSignature());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1910
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1911 fd = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1912 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1913 if (vtbl)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1914 (*vtbl)[j] = fd;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1915 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1916
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1917 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1918 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1919
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1920 void BaseClass::copyBaseInterfaces(BaseClasses *vtblInterfaces)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1921 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1922 //printf("+copyBaseInterfaces(), %s\n", sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1923 // if (baseInterfaces.length)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1924 // return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1925
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1926 baseInterfaces.length = sym->interfaces.length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1927 baseInterfaces.ptr = (BaseClass *)mem.xcalloc(baseInterfaces.length, sizeof(BaseClass));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1928
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1929 //printf("%s.copyBaseInterfaces()\n", sym->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1930 for (size_t i = 0; i < baseInterfaces.length; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1931 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1932 void *pb = &baseInterfaces.ptr[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1933 BaseClass *b2 = sym->interfaces.ptr[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1934
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1935 assert(b2->vtbl.dim == 0); // should not be filled yet
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1936 BaseClass *b = (BaseClass *)memcpy(pb, b2, sizeof(BaseClass));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1937
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1938 if (i) // single inheritance is i==0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1939 vtblInterfaces->push(b); // only need for M.I.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1940 b->copyBaseInterfaces(vtblInterfaces);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1941 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1942 //printf("-copyBaseInterfaces\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1943 }