1 2/* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved 4 * written by Walter Bright 5 * https://www.digitalmars.com 6 * Distributed under the Boost Software License, Version 1.0. 7 * https://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 "dsymbol.h" 14#include "objc.h" 15 16class AliasThis; 17class Identifier; 18class Type; 19class TypeFunction; 20class Expression; 21class FuncDeclaration; 22class CtorDeclaration; 23class DtorDeclaration; 24class InterfaceDeclaration; 25class TypeInfoClassDeclaration; 26class VarDeclaration; 27 28enum class Sizeok : uint8_t 29{ 30 none, // size of aggregate is not yet able to compute 31 fwd, // size of aggregate is ready to compute 32 inProcess, // in the midst of computing the size 33 done // size of aggregate is set correctly 34}; 35 36enum class Baseok : uint8_t 37{ 38 none, // base classes not computed yet 39 in, // in process of resolving base classes 40 done, // all base classes are resolved 41 semanticdone // all base classes semantic done 42}; 43 44enum class ThreeState : uint8_t 45{ 46 none, // value not yet computed 47 no, // value is false 48 yes, // value is true 49}; 50 51FuncDeclaration *search_toString(StructDeclaration *sd); 52 53enum class ClassKind : uint8_t 54{ 55 /// the aggregate is a d(efault) struct/class/interface 56 d, 57 /// the aggregate is a C++ struct/class/interface 58 cpp, 59 /// the aggregate is an Objective-C class/interface 60 objc, 61 /// the aggregate is a C struct 62 c, 63}; 64 65struct MangleOverride 66{ 67 Dsymbol *agg; 68 Identifier *id; 69}; 70 71class AggregateDeclaration : public ScopeDsymbol 72{ 73public: 74 Type *type; 75 StorageClass storage_class; 76 unsigned structsize; // size of struct 77 unsigned alignsize; // size of struct for alignment purposes 78 VarDeclarations fields; // VarDeclaration fields 79 Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol 80 81 ClassKind classKind; // specifies the linkage type 82 CPPMANGLE cppmangle; 83 84 // overridden symbol with pragma(mangle, "...") 85 MangleOverride *mangleOverride; 86 /* !=NULL if is nested 87 * pointing to the dsymbol that directly enclosing it. 88 * 1. The function that enclosing it (nested struct and class) 89 * 2. The class that enclosing it (nested class only) 90 * 3. If enclosing aggregate is template, its enclosing dsymbol. 91 * See AggregateDeclaraton::makeNested for the details. 92 */ 93 Dsymbol *enclosing; 94 VarDeclaration *vthis; // 'this' parameter if this aggregate is nested 95 VarDeclaration *vthis2; // 'this' parameter if this aggregate is a template and is nested 96 // Special member functions 97 FuncDeclarations invs; // Array of invariants 98 FuncDeclaration *inv; // invariant 99 100 Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration 101 102 // default constructor - should have no arguments, because 103 // it would be stored in TypeInfo_Class.defaultConstructor 104 CtorDeclaration *defaultCtor; 105 106 AliasThis *aliasthis; // forward unresolved lookups to aliasthis 107 108 DtorDeclarations userDtors; // user-defined destructors (`~this()`) - mixins can yield multiple ones 109 DtorDeclaration *aggrDtor; // aggregate destructor calling userDtors and fieldDtor (and base class aggregate dtor for C++ classes) 110 DtorDeclaration *dtor; // the aggregate destructor exposed as `__xdtor` alias 111 // (same as aggrDtor, except for C++ classes with virtual dtor on Windows) 112 DtorDeclaration *tidtor; // aggregate destructor used in TypeInfo (must have extern(D) ABI) 113 DtorDeclaration *fieldDtor; // function destructing (non-inherited) fields 114 115 Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this) 116 117 Visibility visibility; 118 bool noDefaultCtor; // no default construction 119 bool disableNew; // disallow allocations using `new` 120 Sizeok sizeok; // set when structsize contains valid data 121 122 virtual Scope *newScope(Scope *sc); 123 void setScope(Scope *sc); 124 size_t nonHiddenFields(); 125 bool determineSize(const Loc &loc); 126 virtual void finalizeSize() = 0; 127 uinteger_t size(const Loc &loc); 128 bool fill(const Loc &loc, Expressions *elements, bool ctorinit); 129 Type *getType(); 130 bool isDeprecated() const; // is aggregate deprecated? 131 void setDeprecated(); 132 bool isNested() const; 133 bool isExport() const; 134 Dsymbol *searchCtor(); 135 136 Visibility visible(); 137 138 // 'this' type 139 Type *handleType() { return type; } 140 141 bool hasInvariant(); 142 143 // Back end 144 void *sinit; 145 146 AggregateDeclaration *isAggregateDeclaration() { return this; } 147 void accept(Visitor *v) { v->visit(this); } 148}; 149 150struct StructFlags 151{ 152 enum Type 153 { 154 none = 0x0, 155 hasPointers = 0x1 // NB: should use noPointers as in ClassFlags 156 }; 157}; 158 159class StructDeclaration : public AggregateDeclaration 160{ 161public: 162 bool zeroInit; // !=0 if initialize with 0 fill 163 bool hasIdentityAssign; // true if has identity opAssign 164 bool hasBlitAssign; // true if opAssign is a blit 165 bool hasIdentityEquals; // true if has identity opEquals 166 bool hasNoFields; // has no fields 167 bool hasCopyCtor; // copy constructor 168 // Even if struct is defined as non-root symbol, some built-in operations 169 // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo. 170 // For those, today TypeInfo_Struct is generated in COMDAT. 171 bool requestTypeInfo; 172 173 FuncDeclarations postblits; // Array of postblit functions 174 FuncDeclaration *postblit; // aggregate postblit 175 176 FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals 177 FuncDeclaration *xcmp; // TypeInfo_Struct.xopCmp 178 FuncDeclaration *xhash; // TypeInfo_Struct.xtoHash 179 static FuncDeclaration *xerreq; // object.xopEquals 180 static FuncDeclaration *xerrcmp; // object.xopCmp 181 182 structalign_t alignment; // alignment applied outside of the struct 183 ThreeState ispod; // if struct is POD 184 185 // ABI-specific type(s) if the struct can be passed in registers 186 TypeTuple *argTypes; 187 188 static StructDeclaration *create(const Loc &loc, Identifier *id, bool inObject); 189 StructDeclaration *syntaxCopy(Dsymbol *s); 190 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); 191 const char *kind() const; 192 void finalizeSize(); 193 bool isPOD(); 194 195 StructDeclaration *isStructDeclaration() { return this; } 196 void accept(Visitor *v) { v->visit(this); } 197 198 unsigned numArgTypes() const; 199 Type *argType(unsigned index); 200 bool hasRegularCtor(bool checkDisabled = false); 201}; 202 203class UnionDeclaration : public StructDeclaration 204{ 205public: 206 UnionDeclaration *syntaxCopy(Dsymbol *s); 207 const char *kind() const; 208 209 UnionDeclaration *isUnionDeclaration() { return this; } 210 void accept(Visitor *v) { v->visit(this); } 211}; 212 213struct BaseClass 214{ 215 Type *type; // (before semantic processing) 216 217 ClassDeclaration *sym; 218 unsigned offset; // 'this' pointer offset 219 // for interfaces: Array of FuncDeclaration's 220 // making up the vtbl[] 221 FuncDeclarations vtbl; 222 223 DArray<BaseClass> baseInterfaces; // if BaseClass is an interface, these 224 // are a copy of the InterfaceDeclaration::interfaces 225 226 bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance); 227}; 228 229struct ClassFlags 230{ 231 enum Type 232 { 233 none = 0x0, 234 isCOMclass = 0x1, 235 noPointers = 0x2, 236 hasOffTi = 0x4, 237 hasCtor = 0x8, 238 hasGetMembers = 0x10, 239 hasTypeInfo = 0x20, 240 isAbstract = 0x40, 241 isCPPclass = 0x80, 242 hasDtor = 0x100 243 }; 244}; 245 246class ClassDeclaration : public AggregateDeclaration 247{ 248public: 249 static ClassDeclaration *object; 250 static ClassDeclaration *throwable; 251 static ClassDeclaration *exception; 252 static ClassDeclaration *errorException; 253 static ClassDeclaration *cpp_type_info_ptr; 254 255 ClassDeclaration *baseClass; // NULL only if this is Object 256 FuncDeclaration *staticCtor; 257 FuncDeclaration *staticDtor; 258 Dsymbols vtbl; // Array of FuncDeclaration's making up the vtbl[] 259 Dsymbols vtblFinal; // More FuncDeclaration's that aren't in vtbl[] 260 261 BaseClasses *baseclasses; // Array of BaseClass's; first is super, 262 // rest are Interface's 263 264 DArray<BaseClass*> interfaces; // interfaces[interfaces_dim] for this class 265 // (does not include baseClass) 266 267 BaseClasses *vtblInterfaces; // array of base interfaces that have 268 // their own vtbl[] 269 270 TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration 271 bool com; // true if this is a COM class (meaning it derives from IUnknown) 272 bool stack; // true if this is a scope class 273 int cppDtorVtblIndex; // slot reserved for the virtual destructor [extern(C++)] 274 bool inuse; // to prevent recursive attempts 275 276 ThreeState isabstract; // if abstract class 277 Baseok baseok; // set the progress of base classes resolving 278 ObjcClassDeclaration objc; // Data for a class declaration that is needed for the Objective-C integration 279 Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr 280 281 static ClassDeclaration *create(const Loc &loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject); 282 const char *toPrettyChars(bool QualifyTypes = false); 283 ClassDeclaration *syntaxCopy(Dsymbol *s); 284 Scope *newScope(Scope *sc); 285 bool isBaseOf2(ClassDeclaration *cd); 286 287 #define OFFSET_RUNTIME 0x76543210 288 #define OFFSET_FWDREF 0x76543211 289 virtual bool isBaseOf(ClassDeclaration *cd, int *poffset); 290 291 bool isBaseInfoComplete(); 292 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); 293 ClassDeclaration *searchBase(Identifier *ident); 294 void finalizeSize(); 295 bool hasMonitor(); 296 bool isFuncHidden(FuncDeclaration *fd); 297 FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 298 bool isCOMclass() const; 299 virtual bool isCOMinterface() const; 300 bool isCPPclass() const; 301 virtual bool isCPPinterface() const; 302 bool isAbstract(); 303 virtual int vtblOffset() const; 304 const char *kind() const; 305 306 void addLocalClass(ClassDeclarations *); 307 void addObjcSymbols(ClassDeclarations *classes, ClassDeclarations *categories); 308 309 // Back end 310 Dsymbol *vtblsym; 311 Dsymbol *vtblSymbol(); 312 313 ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 314 void accept(Visitor *v) { v->visit(this); } 315}; 316 317class InterfaceDeclaration : public ClassDeclaration 318{ 319public: 320 InterfaceDeclaration *syntaxCopy(Dsymbol *s); 321 Scope *newScope(Scope *sc); 322 bool isBaseOf(ClassDeclaration *cd, int *poffset); 323 const char *kind() const; 324 int vtblOffset() const; 325 bool isCPPinterface() const; 326 bool isCOMinterface() const; 327 328 InterfaceDeclaration *isInterfaceDeclaration() { return this; } 329 void accept(Visitor *v) { v->visit(this); } 330}; 331