2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.h
13 #include "root/root.h"
16 #include "declaration.h"
23 class FuncDeclaration
;
24 class CtorDeclaration
;
25 class DtorDeclaration
;
26 class InvariantDeclaration
;
28 class DeleteDeclaration
;
29 class InterfaceDeclaration
;
30 class TypeInfoClassDeclaration
;
35 SIZEOKnone
, // size of aggregate is not yet able to compute
36 SIZEOKfwd
, // size of aggregate is ready to compute
37 SIZEOKdone
// size of aggregate is set correctly
42 BASEOKnone
, // base classes not computed yet
43 BASEOKin
, // in process of resolving base classes
44 BASEOKdone
, // all base classes are resolved
45 BASEOKsemanticdone
// all base classes semantic done
50 ISPODno
, // struct is not POD
51 ISPODyes
, // struct is POD
52 ISPODfwd
// POD not yet computed
57 ABSfwdref
= 0, // whether an abstract class is not yet computed
58 ABSyes
, // is abstract class
59 ABSno
// is not abstract class
62 FuncDeclaration
*hasIdentityOpAssign(AggregateDeclaration
*ad
, Scope
*sc
);
63 FuncDeclaration
*buildOpAssign(StructDeclaration
*sd
, Scope
*sc
);
64 bool needOpEquals(StructDeclaration
*sd
);
65 FuncDeclaration
*buildOpEquals(StructDeclaration
*sd
, Scope
*sc
);
66 FuncDeclaration
*buildXopEquals(StructDeclaration
*sd
, Scope
*sc
);
67 FuncDeclaration
*buildXopCmp(StructDeclaration
*sd
, Scope
*sc
);
68 FuncDeclaration
*buildXtoHash(StructDeclaration
*ad
, Scope
*sc
);
69 FuncDeclaration
*buildPostBlit(StructDeclaration
*sd
, Scope
*sc
);
70 FuncDeclaration
*buildDtor(AggregateDeclaration
*ad
, Scope
*sc
);
71 FuncDeclaration
*buildInv(AggregateDeclaration
*ad
, Scope
*sc
);
72 FuncDeclaration
*search_toString(StructDeclaration
*sd
);
78 /// the class is a d(efault) class
80 /// the class is a C++ interface
82 /// the class is an Objective-C class/interface
87 class AggregateDeclaration
: public ScopeDsymbol
91 StorageClass storage_class
;
93 unsigned structsize
; // size of struct
94 unsigned alignsize
; // size of struct for alignment purposes
95 VarDeclarations fields
; // VarDeclaration fields
96 Sizeok sizeok
; // set when structsize contains valid data
97 Dsymbol
*deferred
; // any deferred semantic2() or semantic3() symbol
98 bool isdeprecated
; // true if deprecated
100 ClassKind::Type classKind
; // specifies the linkage type
102 /* !=NULL if is nested
103 * pointing to the dsymbol that directly enclosing it.
104 * 1. The function that enclosing it (nested struct and class)
105 * 2. The class that enclosing it (nested class only)
106 * 3. If enclosing aggregate is template, its enclosing dsymbol.
107 * See AggregateDeclaraton::makeNested for the details.
110 VarDeclaration
*vthis
; // 'this' parameter if this aggregate is nested
111 // Special member functions
112 FuncDeclarations invs
; // Array of invariants
113 FuncDeclaration
*inv
; // invariant
114 NewDeclaration
*aggNew
; // allocator
115 DeleteDeclaration
*aggDelete
; // deallocator
117 Dsymbol
*ctor
; // CtorDeclaration or TemplateDeclaration
119 // default constructor - should have no arguments, because
120 // it would be stored in TypeInfo_Class.defaultConstructor
121 CtorDeclaration
*defaultCtor
;
123 Dsymbol
*aliasthis
; // forward unresolved lookups to aliasthis
124 bool noDefaultCtor
; // no default construction
126 FuncDeclarations dtors
; // Array of destructors
127 FuncDeclaration
*dtor
; // aggregate destructor
129 Expression
*getRTInfo
; // pointer to GC info generated by object.RTInfo(this)
131 AggregateDeclaration(Loc loc
, Identifier
*id
);
132 virtual Scope
*newScope(Scope
*sc
);
133 void setScope(Scope
*sc
);
134 bool determineFields();
135 bool determineSize(Loc loc
);
136 virtual void finalizeSize() = 0;
137 d_uns64
size(Loc loc
);
138 bool checkOverlappedFields();
139 bool fill(Loc loc
, Expressions
*elements
, bool ctorinit
);
140 static void alignmember(structalign_t salign
, unsigned size
, unsigned *poffset
);
141 static unsigned placeField(unsigned *nextoffset
,
142 unsigned memsize
, unsigned memalignsize
, structalign_t memalign
,
143 unsigned *paggsize
, unsigned *paggalignsize
, bool isunion
);
145 bool isDeprecated(); // is aggregate deprecated?
148 bool isExport() const;
149 Dsymbol
*searchCtor();
154 Type
*handleType() { return type
; }
157 Symbol
*stag
; // tag symbol for debug data
160 AggregateDeclaration
*isAggregateDeclaration() { return this; }
161 void accept(Visitor
*v
) { v
->visit(this); }
166 typedef unsigned Type
;
170 hasPointers
= 0x1 // NB: should use noPointers as in ClassFlags
174 class StructDeclaration
: public AggregateDeclaration
177 int zeroInit
; // !=0 if initialize with 0 fill
178 bool hasIdentityAssign
; // true if has identity opAssign
179 bool hasIdentityEquals
; // true if has identity opEquals
180 FuncDeclarations postblits
; // Array of postblit functions
181 FuncDeclaration
*postblit
; // aggregate postblit
183 FuncDeclaration
*xeq
; // TypeInfo_Struct.xopEquals
184 FuncDeclaration
*xcmp
; // TypeInfo_Struct.xopCmp
185 FuncDeclaration
*xhash
; // TypeInfo_Struct.xtoHash
186 static FuncDeclaration
*xerreq
; // object.xopEquals
187 static FuncDeclaration
*xerrcmp
; // object.xopCmp
189 structalign_t alignment
; // alignment applied outside of the struct
190 StructPOD ispod
; // if struct is POD
192 // For 64 bit Efl function call/return ABI
196 // Even if struct is defined as non-root symbol, some built-in operations
197 // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
198 // For those, today TypeInfo_Struct is generated in COMDAT.
199 bool requestTypeInfo
;
201 StructDeclaration(Loc loc
, Identifier
*id
, bool inObject
);
202 static StructDeclaration
*create(Loc loc
, Identifier
*id
, bool inObject
);
203 Dsymbol
*syntaxCopy(Dsymbol
*s
);
204 void semanticTypeInfoMembers();
205 Dsymbol
*search(const Loc
&loc
, Identifier
*ident
, int flags
= SearchLocalsOnly
);
206 const char *kind() const;
208 bool fit(Loc loc
, Scope
*sc
, Expressions
*elements
, Type
*stype
);
211 StructDeclaration
*isStructDeclaration() { return this; }
212 void accept(Visitor
*v
) { v
->visit(this); }
215 class UnionDeclaration
: public StructDeclaration
218 UnionDeclaration(Loc loc
, Identifier
*id
);
219 Dsymbol
*syntaxCopy(Dsymbol
*s
);
220 const char *kind() const;
222 UnionDeclaration
*isUnionDeclaration() { return this; }
223 void accept(Visitor
*v
) { v
->visit(this); }
228 Type
*type
; // (before semantic processing)
230 ClassDeclaration
*sym
;
231 unsigned offset
; // 'this' pointer offset
232 // for interfaces: Array of FuncDeclaration's
233 // making up the vtbl[]
234 FuncDeclarations vtbl
;
236 DArray
<BaseClass
> baseInterfaces
; // if BaseClass is an interface, these
237 // are a copy of the InterfaceDeclaration::interfaces
240 BaseClass(Type
*type
);
242 bool fillVtbl(ClassDeclaration
*cd
, FuncDeclarations
*vtbl
, int newinstance
);
243 void copyBaseInterfaces(BaseClasses
*);
248 typedef unsigned Type
;
255 hasGetMembers
= 0x10,
263 class ClassDeclaration
: public AggregateDeclaration
266 static ClassDeclaration
*object
;
267 static ClassDeclaration
*throwable
;
268 static ClassDeclaration
*exception
;
269 static ClassDeclaration
*errorException
;
270 static ClassDeclaration
*cpp_type_info_ptr
;
272 ClassDeclaration
*baseClass
; // NULL only if this is Object
273 FuncDeclaration
*staticCtor
;
274 FuncDeclaration
*staticDtor
;
275 Dsymbols vtbl
; // Array of FuncDeclaration's making up the vtbl[]
276 Dsymbols vtblFinal
; // More FuncDeclaration's that aren't in vtbl[]
278 BaseClasses
*baseclasses
; // Array of BaseClass's; first is super,
279 // rest are Interface's
281 DArray
<BaseClass
*> interfaces
; // interfaces[interfaces_dim] for this class
282 // (does not include baseClass)
284 BaseClasses
*vtblInterfaces
; // array of base interfaces that have
287 TypeInfoClassDeclaration
*vclassinfo
; // the ClassInfo object for this ClassDeclaration
288 bool com
; // true if this is a COM class (meaning it derives from IUnknown)
289 bool isscope
; // true if this is a scope class
290 Abstract isabstract
; // 0: fwdref, 1: is abstract class, 2: not abstract
291 int inuse
; // to prevent recursive attempts
292 Baseok baseok
; // set the progress of base classes resolving
293 Symbol
*cpp_type_info_ptr_sym
; // cached instance of class Id.cpp_type_info_ptr
295 ClassDeclaration(Loc loc
, Identifier
*id
, BaseClasses
*baseclasses
, Dsymbols
*members
, bool inObject
= false);
296 static ClassDeclaration
*create(Loc loc
, Identifier
*id
, BaseClasses
*baseclasses
, Dsymbols
*members
, bool inObject
);
297 Dsymbol
*syntaxCopy(Dsymbol
*s
);
298 Scope
*newScope(Scope
*sc
);
299 bool isBaseOf2(ClassDeclaration
*cd
);
301 #define OFFSET_RUNTIME 0x76543210
302 #define OFFSET_FWDREF 0x76543211
303 virtual bool isBaseOf(ClassDeclaration
*cd
, int *poffset
);
305 bool isBaseInfoComplete();
306 Dsymbol
*search(const Loc
&loc
, Identifier
*ident
, int flags
= SearchLocalsOnly
);
307 ClassDeclaration
*searchBase(Identifier
*ident
);
310 bool isFuncHidden(FuncDeclaration
*fd
);
311 FuncDeclaration
*findFunc(Identifier
*ident
, TypeFunction
*tf
);
312 bool isCOMclass() const;
313 virtual bool isCOMinterface() const;
314 bool isCPPclass() const;
315 virtual bool isCPPinterface() const;
317 virtual int vtblOffset() const;
318 const char *kind() const;
320 void addLocalClass(ClassDeclarations
*);
325 ClassDeclaration
*isClassDeclaration() { return (ClassDeclaration
*)this; }
326 void accept(Visitor
*v
) { v
->visit(this); }
329 class InterfaceDeclaration
: public ClassDeclaration
332 InterfaceDeclaration(Loc loc
, Identifier
*id
, BaseClasses
*baseclasses
);
333 Dsymbol
*syntaxCopy(Dsymbol
*s
);
334 Scope
*newScope(Scope
*sc
);
335 bool isBaseOf(ClassDeclaration
*cd
, int *poffset
);
336 bool isBaseOf(BaseClass
*bc
, int *poffset
);
337 const char *kind() const;
338 int vtblOffset() const;
339 bool isCPPinterface() const;
340 bool isCOMinterface() const;
342 InterfaceDeclaration
*isInterfaceDeclaration() { return this; }
343 void accept(Visitor
*v
) { v
->visit(this); }