1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 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 9 */ 10 11 #pragma once 12 13 #include "root/root.h" 14 15 #include "dsymbol.h" 16 #include "declaration.h" 17 #include "objc.h" 18 19 class Identifier; 20 class Type; 21 class TypeFunction; 22 class Expression; 23 class FuncDeclaration; 24 class CtorDeclaration; 25 class DtorDeclaration; 26 class InvariantDeclaration; 27 class NewDeclaration; 28 class DeleteDeclaration; 29 class InterfaceDeclaration; 30 class TypeInfoClassDeclaration; 31 class VarDeclaration; 32 33 enum Sizeok 34 { 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 38 }; 39 40 enum Baseok 41 { 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 46 }; 47 48 enum StructPOD 49 { 50 ISPODno, // struct is not POD 51 ISPODyes, // struct is POD 52 ISPODfwd // POD not yet computed 53 }; 54 55 enum Abstract 56 { 57 ABSfwdref = 0, // whether an abstract class is not yet computed 58 ABSyes, // is abstract class 59 ABSno // is not abstract class 60 }; 61 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); 73 74 class AggregateDeclaration : public ScopeDsymbol 75 { 76 public: 77 Type *type; 78 StorageClass storage_class; 79 Prot protection; 80 unsigned structsize; // size of struct 81 unsigned alignsize; // size of struct for alignment purposes 82 VarDeclarations fields; // VarDeclaration fields 83 Sizeok sizeok; // set when structsize contains valid data 84 Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol 85 bool isdeprecated; // true if deprecated 86 87 /* !=NULL if is nested 88 * pointing to the dsymbol that directly enclosing it. 89 * 1. The function that enclosing it (nested struct and class) 90 * 2. The class that enclosing it (nested class only) 91 * 3. If enclosing aggregate is template, its enclosing dsymbol. 92 * See AggregateDeclaraton::makeNested for the details. 93 */ 94 Dsymbol *enclosing; 95 VarDeclaration *vthis; // 'this' parameter if this aggregate is nested 96 // Special member functions 97 FuncDeclarations invs; // Array of invariants 98 FuncDeclaration *inv; // invariant 99 NewDeclaration *aggNew; // allocator 100 DeleteDeclaration *aggDelete; // deallocator 101 102 Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration 103 104 // default constructor - should have no arguments, because 105 // it would be stored in TypeInfo_Class.defaultConstructor 106 CtorDeclaration *defaultCtor; 107 108 Dsymbol *aliasthis; // forward unresolved lookups to aliasthis 109 bool noDefaultCtor; // no default construction 110 111 FuncDeclarations dtors; // Array of destructors 112 FuncDeclaration *dtor; // aggregate destructor 113 114 Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this) 115 116 AggregateDeclaration(Loc loc, Identifier *id); 117 virtual Scope *newScope(Scope *sc); 118 void setScope(Scope *sc); 119 void semantic2(Scope *sc); 120 void semantic3(Scope *sc); 121 bool determineFields(); 122 bool determineSize(Loc loc); 123 virtual void finalizeSize() = 0; 124 d_uns64 size(Loc loc); 125 bool checkOverlappedFields(); 126 bool fill(Loc loc, Expressions *elements, bool ctorinit); 127 static void alignmember(structalign_t salign, unsigned size, unsigned *poffset); 128 static unsigned placeField(unsigned *nextoffset, 129 unsigned memsize, unsigned memalignsize, structalign_t memalign, 130 unsigned *paggsize, unsigned *paggalignsize, bool isunion); 131 Type *getType(); 132 bool isDeprecated(); // is aggregate deprecated? 133 bool isNested(); 134 void makeNested(); 135 bool isExport() const; 136 Dsymbol *searchCtor(); 137 138 Prot prot(); 139 140 // 'this' type handleType()141 Type *handleType() { return type; } 142 143 // Back end 144 Symbol *stag; // tag symbol for debug data 145 Symbol *sinit; 146 isAggregateDeclaration()147 AggregateDeclaration *isAggregateDeclaration() { return this; } accept(Visitor * v)148 void accept(Visitor *v) { v->visit(this); } 149 }; 150 151 struct StructFlags 152 { 153 typedef unsigned Type; 154 enum Enum 155 { 156 none = 0x0, 157 hasPointers = 0x1 // NB: should use noPointers as in ClassFlags 158 }; 159 }; 160 161 class StructDeclaration : public AggregateDeclaration 162 { 163 public: 164 int zeroInit; // !=0 if initialize with 0 fill 165 bool hasIdentityAssign; // true if has identity opAssign 166 bool hasIdentityEquals; // true if has identity opEquals 167 FuncDeclarations postblits; // Array of postblit functions 168 FuncDeclaration *postblit; // aggregate postblit 169 170 FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals 171 FuncDeclaration *xcmp; // TypeInfo_Struct.xopCmp 172 FuncDeclaration *xhash; // TypeInfo_Struct.xtoHash 173 static FuncDeclaration *xerreq; // object.xopEquals 174 static FuncDeclaration *xerrcmp; // object.xopCmp 175 176 structalign_t alignment; // alignment applied outside of the struct 177 StructPOD ispod; // if struct is POD 178 179 // For 64 bit Efl function call/return ABI 180 Type *arg1type; 181 Type *arg2type; 182 183 // Even if struct is defined as non-root symbol, some built-in operations 184 // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo. 185 // For those, today TypeInfo_Struct is generated in COMDAT. 186 bool requestTypeInfo; 187 188 StructDeclaration(Loc loc, Identifier *id, bool inObject); 189 static StructDeclaration *create(Loc loc, Identifier *id, bool inObject); 190 Dsymbol *syntaxCopy(Dsymbol *s); 191 void semantic(Scope *sc); 192 void semanticTypeInfoMembers(); 193 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); 194 const char *kind() const; 195 void finalizeSize(); 196 bool fit(Loc loc, Scope *sc, Expressions *elements, Type *stype); 197 bool isPOD(); 198 isStructDeclaration()199 StructDeclaration *isStructDeclaration() { return this; } accept(Visitor * v)200 void accept(Visitor *v) { v->visit(this); } 201 }; 202 203 class UnionDeclaration : public StructDeclaration 204 { 205 public: 206 UnionDeclaration(Loc loc, Identifier *id); 207 Dsymbol *syntaxCopy(Dsymbol *s); 208 const char *kind() const; 209 isUnionDeclaration()210 UnionDeclaration *isUnionDeclaration() { return this; } accept(Visitor * v)211 void accept(Visitor *v) { v->visit(this); } 212 }; 213 214 struct BaseClass 215 { 216 Type *type; // (before semantic processing) 217 218 ClassDeclaration *sym; 219 unsigned offset; // 'this' pointer offset 220 // for interfaces: Array of FuncDeclaration's 221 // making up the vtbl[] 222 FuncDeclarations vtbl; 223 224 DArray<BaseClass> baseInterfaces; // if BaseClass is an interface, these 225 // are a copy of the InterfaceDeclaration::interfaces 226 227 BaseClass(); 228 BaseClass(Type *type); 229 230 bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance); 231 void copyBaseInterfaces(BaseClasses *); 232 }; 233 234 struct ClassFlags 235 { 236 typedef unsigned Type; 237 enum Enum 238 { 239 isCOMclass = 0x1, 240 noPointers = 0x2, 241 hasOffTi = 0x4, 242 hasCtor = 0x8, 243 hasGetMembers = 0x10, 244 hasTypeInfo = 0x20, 245 isAbstract = 0x40, 246 isCPPclass = 0x80, 247 hasDtor = 0x100 248 }; 249 }; 250 251 class ClassDeclaration : public AggregateDeclaration 252 { 253 public: 254 static ClassDeclaration *object; 255 static ClassDeclaration *throwable; 256 static ClassDeclaration *exception; 257 static ClassDeclaration *errorException; 258 static ClassDeclaration *cpp_type_info_ptr; 259 260 ClassDeclaration *baseClass; // NULL only if this is Object 261 FuncDeclaration *staticCtor; 262 FuncDeclaration *staticDtor; 263 Dsymbols vtbl; // Array of FuncDeclaration's making up the vtbl[] 264 Dsymbols vtblFinal; // More FuncDeclaration's that aren't in vtbl[] 265 266 BaseClasses *baseclasses; // Array of BaseClass's; first is super, 267 // rest are Interface's 268 269 DArray<BaseClass*> interfaces; // interfaces[interfaces_dim] for this class 270 // (does not include baseClass) 271 272 BaseClasses *vtblInterfaces; // array of base interfaces that have 273 // their own vtbl[] 274 275 TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration 276 bool com; // true if this is a COM class (meaning it derives from IUnknown) 277 bool cpp; // true if this is a C++ interface 278 bool isobjc; // true if this is an Objective-C class/interface 279 bool isscope; // true if this is a scope class 280 Abstract isabstract; // 0: fwdref, 1: is abstract class, 2: not abstract 281 int inuse; // to prevent recursive attempts 282 Baseok baseok; // set the progress of base classes resolving 283 Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr 284 285 ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject = false); 286 static ClassDeclaration *create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject); 287 Dsymbol *syntaxCopy(Dsymbol *s); 288 Scope *newScope(Scope *sc); 289 void semantic(Scope *sc); 290 bool isBaseOf2(ClassDeclaration *cd); 291 292 #define OFFSET_RUNTIME 0x76543210 293 #define OFFSET_FWDREF 0x76543211 294 virtual bool isBaseOf(ClassDeclaration *cd, int *poffset); 295 296 bool isBaseInfoComplete(); 297 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); 298 ClassDeclaration *searchBase(Identifier *ident); 299 void finalizeSize(); 300 bool isFuncHidden(FuncDeclaration *fd); 301 FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 302 void interfaceSemantic(Scope *sc); 303 bool isCOMclass() const; 304 virtual bool isCOMinterface() const; 305 bool isCPPclass() const; 306 virtual bool isCPPinterface() const; 307 bool isAbstract(); 308 virtual int vtblOffset() const; 309 const char *kind() const; 310 311 void addLocalClass(ClassDeclarations *); 312 313 // Back end 314 Symbol *vtblsym; 315 isClassDeclaration()316 ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } accept(Visitor * v)317 void accept(Visitor *v) { v->visit(this); } 318 }; 319 320 class InterfaceDeclaration : public ClassDeclaration 321 { 322 public: 323 InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 324 Dsymbol *syntaxCopy(Dsymbol *s); 325 Scope *newScope(Scope *sc); 326 void semantic(Scope *sc); 327 bool isBaseOf(ClassDeclaration *cd, int *poffset); 328 bool isBaseOf(BaseClass *bc, int *poffset); 329 const char *kind() const; 330 int vtblOffset() const; 331 bool isCPPinterface() const; 332 bool isCOMinterface() const; 333 isInterfaceDeclaration()334 InterfaceDeclaration *isInterfaceDeclaration() { return this; } accept(Visitor * v)335 void accept(Visitor *v) { v->visit(this); } 336 }; 337