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/D-Programming-Language/dmd/blob/master/src/struct.c
9 */
10
11 #include "root/dsystem.h"
12 #include "root/root.h"
13
14 #include "errors.h"
15 #include "aggregate.h"
16 #include "scope.h"
17 #include "mtype.h"
18 #include "init.h"
19 #include "declaration.h"
20 #include "module.h"
21 #include "id.h"
22 #include "statement.h"
23 #include "template.h"
24 #include "tokens.h"
25 #include "target.h"
26
27 Type *getTypeInfoType(Loc loc, Type *t, Scope *sc);
28 void unSpeculative(Scope *sc, RootObject *o);
29 bool MODimplicitConv(MOD modfrom, MOD modto);
30 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
31
32 FuncDeclaration *StructDeclaration::xerreq; // object.xopEquals
33 FuncDeclaration *StructDeclaration::xerrcmp; // object.xopCmp
34
35 /***************************************
36 * Search toString member function for TypeInfo_Struct.
37 * string toString();
38 */
search_toString(StructDeclaration * sd)39 FuncDeclaration *search_toString(StructDeclaration *sd)
40 {
41 Dsymbol *s = search_function(sd, Id::tostring);
42 FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
43 if (fd)
44 {
45 static TypeFunction *tftostring;
46 if (!tftostring)
47 {
48 tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd);
49 tftostring = tftostring->merge()->toTypeFunction();
50 }
51
52 fd = fd->overloadExactMatch(tftostring);
53 }
54 return fd;
55 }
56
57 /***************************************
58 * Request additonal semantic analysis for TypeInfo generation.
59 */
semanticTypeInfo(Scope * sc,Type * t)60 void semanticTypeInfo(Scope *sc, Type *t)
61 {
62 class FullTypeInfoVisitor : public Visitor
63 {
64 public:
65 Scope *sc;
66
67 void visit(Type *t)
68 {
69 Type *tb = t->toBasetype();
70 if (tb != t)
71 tb->accept(this);
72 }
73 void visit(TypeNext *t)
74 {
75 if (t->next)
76 t->next->accept(this);
77 }
78 void visit(TypeBasic *) { }
79 void visit(TypeVector *t)
80 {
81 t->basetype->accept(this);
82 }
83 void visit(TypeAArray *t)
84 {
85 t->index->accept(this);
86 visit((TypeNext *)t);
87 }
88 void visit(TypeFunction *t)
89 {
90 visit((TypeNext *)t);
91 // Currently TypeInfo_Function doesn't store parameter types.
92 }
93 void visit(TypeStruct *t)
94 {
95 //printf("semanticTypeInfo::visit(TypeStruct = %s)\n", t->toChars());
96 StructDeclaration *sd = t->sym;
97
98 /* Step 1: create TypeInfoDeclaration
99 */
100 if (!sc) // inline may request TypeInfo.
101 {
102 Scope scx;
103 scx._module = sd->getModule();
104 getTypeInfoType(sd->loc, t, &scx);
105 sd->requestTypeInfo = true;
106 }
107 else if (!sc->minst)
108 {
109 // don't yet have to generate TypeInfo instance if
110 // the typeid(T) expression exists in speculative scope.
111 }
112 else
113 {
114 getTypeInfoType(sd->loc, t, sc);
115 sd->requestTypeInfo = true;
116
117 // Bugzilla 15149, if the typeid operand type comes from a
118 // result of auto function, it may be yet speculative.
119 // unSpeculative(sc, sd);
120 }
121
122 /* Step 2: If the TypeInfo generation requires sd.semantic3, run it later.
123 * This should be done even if typeid(T) exists in speculative scope.
124 * Because it may appear later in non-speculative scope.
125 */
126 if (!sd->members)
127 return; // opaque struct
128 if (!sd->xeq && !sd->xcmp && !sd->postblit &&
129 !sd->dtor && !sd->xhash && !search_toString(sd))
130 return; // none of TypeInfo-specific members
131
132 // If the struct is in a non-root module, run semantic3 to get
133 // correct symbols for the member function.
134 if (sd->semanticRun >= PASSsemantic3)
135 {
136 // semantic3 is already done
137 }
138 else if (TemplateInstance *ti = sd->isInstantiated())
139 {
140 if (ti->minst && !ti->minst->isRoot())
141 Module::addDeferredSemantic3(sd);
142 }
143 else
144 {
145 if (sd->inNonRoot())
146 {
147 //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot());
148 Module::addDeferredSemantic3(sd);
149 }
150 }
151 }
152 void visit(TypeClass *) { }
153 void visit(TypeTuple *t)
154 {
155 if (t->arguments)
156 {
157 for (size_t i = 0; i < t->arguments->dim; i++)
158 {
159 Type *tprm = (*t->arguments)[i]->type;
160 if (tprm)
161 tprm->accept(this);
162 }
163 }
164 }
165 };
166
167 if (sc)
168 {
169 if (!sc->func)
170 return;
171 if (sc->intypeof)
172 return;
173 if (sc->flags & (SCOPEctfe | SCOPEcompile))
174 return;
175 }
176
177 FullTypeInfoVisitor v;
178 v.sc = sc;
179 t->accept(&v);
180 }
181
182 /********************************* AggregateDeclaration ****************************/
183
AggregateDeclaration(Loc loc,Identifier * id)184 AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
185 : ScopeDsymbol(id)
186 {
187 this->loc = loc;
188
189 storage_class = 0;
190 protection = Prot(PROTpublic);
191 type = NULL;
192 structsize = 0; // size of struct
193 alignsize = 0; // size of struct for alignment purposes
194 sizeok = SIZEOKnone; // size not determined yet
195 deferred = NULL;
196 isdeprecated = false;
197 classKind = ClassKind::d;
198 inv = NULL;
199 aggNew = NULL;
200 aggDelete = NULL;
201
202 stag = NULL;
203 sinit = NULL;
204 enclosing = NULL;
205 vthis = NULL;
206
207 ctor = NULL;
208 defaultCtor = NULL;
209 aliasthis = NULL;
210 noDefaultCtor = false;
211 dtor = NULL;
212 getRTInfo = NULL;
213 }
214
prot()215 Prot AggregateDeclaration::prot()
216 {
217 return protection;
218 }
219
220 /***************************************
221 * Create a new scope from sc.
222 * semantic, semantic2 and semantic3 will use this for aggregate members.
223 */
newScope(Scope * sc)224 Scope *AggregateDeclaration::newScope(Scope *sc)
225 {
226 Scope *sc2 = sc->push(this);
227 sc2->stc &= STCsafe | STCtrusted | STCsystem;
228 sc2->parent = this;
229 if (isUnionDeclaration())
230 sc2->inunion = 1;
231 sc2->protection = Prot(PROTpublic);
232 sc2->explicitProtection = 0;
233 sc2->aligndecl = NULL;
234 sc2->userAttribDecl = NULL;
235 return sc2;
236 }
237
setScope(Scope * sc)238 void AggregateDeclaration::setScope(Scope *sc)
239 {
240 // Might need a scope to resolve forward references. The check for
241 // semanticRun prevents unnecessary setting of _scope during deferred
242 // setScope phases for aggregates which already finished semantic().
243 // Also see https://issues.dlang.org/show_bug.cgi?id=16607
244 if (semanticRun < PASSsemanticdone)
245 ScopeDsymbol::setScope(sc);
246 }
247
semantic2(Scope * sc)248 void AggregateDeclaration::semantic2(Scope *sc)
249 {
250 //printf("AggregateDeclaration::semantic2(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors);
251 if (!members)
252 return;
253
254 if (_scope)
255 {
256 error("has forward references");
257 return;
258 }
259
260 Scope *sc2 = newScope(sc);
261
262 determineSize(loc);
263
264 for (size_t i = 0; i < members->dim; i++)
265 {
266 Dsymbol *s = (*members)[i];
267 //printf("\t[%d] %s\n", i, s->toChars());
268 s->semantic2(sc2);
269 }
270
271 sc2->pop();
272 }
273
semantic3(Scope * sc)274 void AggregateDeclaration::semantic3(Scope *sc)
275 {
276 //printf("AggregateDeclaration::semantic3(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors);
277 if (!members)
278 return;
279
280 StructDeclaration *sd = isStructDeclaration();
281 if (!sc) // from runDeferredSemantic3 for TypeInfo generation
282 {
283 assert(sd);
284 sd->semanticTypeInfoMembers();
285 return;
286 }
287
288 Scope *sc2 = newScope(sc);
289
290 for (size_t i = 0; i < members->dim; i++)
291 {
292 Dsymbol *s = (*members)[i];
293 s->semantic3(sc2);
294 }
295
296 sc2->pop();
297
298 // don't do it for unused deprecated types
299 // or error types
300 if (!getRTInfo && Type::rtinfo &&
301 (!isDeprecated() || global.params.useDeprecated != DIAGNOSTICerror) &&
302 (type && type->ty != Terror))
303 {
304 // Evaluate: RTinfo!type
305 Objects *tiargs = new Objects();
306 tiargs->push(type);
307 TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs);
308
309 Scope *sc3 = ti->tempdecl->_scope->startCTFE();
310 sc3->tinst = sc->tinst;
311 sc3->minst = sc->minst;
312 if (isDeprecated())
313 sc3->stc |= STCdeprecated;
314
315 ti->semantic(sc3);
316 ti->semantic2(sc3);
317 ti->semantic3(sc3);
318 Expression *e = resolve(Loc(), sc3, ti->toAlias(), false);
319
320 sc3->endCTFE();
321
322 e = e->ctfeInterpret();
323 getRTInfo = e;
324 }
325
326 if (sd)
327 sd->semanticTypeInfoMembers();
328 semanticRun = PASSsemantic3done;
329 }
330
331 /***************************************
332 * Find all instance fields, then push them into `fields`.
333 *
334 * Runs semantic() for all instance field variables, but also
335 * the field types can reamin yet not resolved forward references,
336 * except direct recursive definitions.
337 * After the process sizeok is set to SIZEOKfwd.
338 *
339 * Returns:
340 * false if any errors occur.
341 */
determineFields()342 bool AggregateDeclaration::determineFields()
343 {
344 if (sizeok != SIZEOKnone)
345 return true;
346
347 //printf("determineFields() %s, fields.dim = %d\n", toChars(), fields.dim);
348 fields.setDim(0);
349
350 struct SV
351 {
352 AggregateDeclaration *agg;
353
354 static int func(Dsymbol *s, void *param)
355 {
356 VarDeclaration *v = s->isVarDeclaration();
357 if (!v)
358 return 0;
359 if (v->storage_class & STCmanifest)
360 return 0;
361
362 AggregateDeclaration *ad = ((SV *)param)->agg;
363
364 if (v->semanticRun < PASSsemanticdone)
365 v->semantic(NULL);
366 // Note: Aggregate fields or size could have determined during v->semantic.
367 if (ad->sizeok != SIZEOKnone)
368 return 1;
369
370 if (v->aliassym)
371 return 0; // If this variable was really a tuple, skip it.
372
373 if (v->storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCctfe | STCtemplateparameter))
374 return 0;
375 if (!v->isField() || v->semanticRun < PASSsemanticdone)
376 return 1; // unresolvable forward reference
377
378 ad->fields.push(v);
379
380 if (v->storage_class & STCref)
381 return 0;
382 Type *tv = v->type->baseElemOf();
383 if (tv->ty != Tstruct)
384 return 0;
385 if (ad == ((TypeStruct *)tv)->sym)
386 {
387 const char *psz = (v->type->toBasetype()->ty == Tsarray) ? "static array of " : "";
388 ad->error("cannot have field %s with %ssame struct type", v->toChars(), psz);
389 ad->type = Type::terror;
390 ad->errors = true;
391 return 1;
392 }
393 return 0;
394 }
395 };
396 SV sv;
397 sv.agg = this;
398
399 for (size_t i = 0; i < members->dim; i++)
400 {
401 Dsymbol *s = (*members)[i];
402 if (s->apply(&SV::func, &sv))
403 {
404 if (sizeok != SIZEOKnone)
405 return true;
406 return false;
407 }
408 }
409
410 if (sizeok != SIZEOKdone)
411 sizeok = SIZEOKfwd;
412
413 return true;
414 }
415
416 /***************************************
417 * Collect all instance fields, then determine instance size.
418 * Returns:
419 * false if failed to determine the size.
420 */
determineSize(Loc loc)421 bool AggregateDeclaration::determineSize(Loc loc)
422 {
423 //printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok);
424
425 // The previous instance size finalizing had:
426 if (type->ty == Terror)
427 return false; // failed already
428 if (sizeok == SIZEOKdone)
429 return true; // succeeded
430
431 if (!members)
432 {
433 error(loc, "unknown size");
434 return false;
435 }
436
437 if (_scope)
438 semantic(NULL);
439
440 // Determine the instance size of base class first.
441 if (ClassDeclaration *cd = isClassDeclaration())
442 {
443 cd = cd->baseClass;
444 if (cd && !cd->determineSize(loc))
445 goto Lfail;
446 }
447
448 // Determine instance fields when sizeok == SIZEOKnone
449 if (!determineFields())
450 goto Lfail;
451 if (sizeok != SIZEOKdone)
452 finalizeSize();
453
454 // this aggregate type has:
455 if (type->ty == Terror)
456 return false; // marked as invalid during the finalizing.
457 if (sizeok == SIZEOKdone)
458 return true; // succeeded to calculate instance size.
459
460 Lfail:
461 // There's unresolvable forward reference.
462 if (type != Type::terror)
463 error(loc, "no size because of forward reference");
464 // Don't cache errors from speculative semantic, might be resolvable later.
465 // https://issues.dlang.org/show_bug.cgi?id=16574
466 if (!global.gag)
467 {
468 type = Type::terror;
469 errors = true;
470 }
471 return false;
472 }
473
semanticTypeInfoMembers()474 void StructDeclaration::semanticTypeInfoMembers()
475 {
476 if (xeq &&
477 xeq->_scope &&
478 xeq->semanticRun < PASSsemantic3done)
479 {
480 unsigned errors = global.startGagging();
481 xeq->semantic3(xeq->_scope);
482 if (global.endGagging(errors))
483 xeq = xerreq;
484 }
485
486 if (xcmp &&
487 xcmp->_scope &&
488 xcmp->semanticRun < PASSsemantic3done)
489 {
490 unsigned errors = global.startGagging();
491 xcmp->semantic3(xcmp->_scope);
492 if (global.endGagging(errors))
493 xcmp = xerrcmp;
494 }
495
496 FuncDeclaration *ftostr = search_toString(this);
497 if (ftostr &&
498 ftostr->_scope &&
499 ftostr->semanticRun < PASSsemantic3done)
500 {
501 ftostr->semantic3(ftostr->_scope);
502 }
503
504 if (xhash &&
505 xhash->_scope &&
506 xhash->semanticRun < PASSsemantic3done)
507 {
508 xhash->semantic3(xhash->_scope);
509 }
510
511 if (postblit &&
512 postblit->_scope &&
513 postblit->semanticRun < PASSsemantic3done)
514 {
515 postblit->semantic3(postblit->_scope);
516 }
517
518 if (dtor &&
519 dtor->_scope &&
520 dtor->semanticRun < PASSsemantic3done)
521 {
522 dtor->semantic3(dtor->_scope);
523 }
524 }
525
size(Loc loc)526 d_uns64 AggregateDeclaration::size(Loc loc)
527 {
528 //printf("+AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok);
529 bool ok = determineSize(loc);
530 //printf("-AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok);
531 return ok ? structsize : SIZE_INVALID;
532 }
533
getType()534 Type *AggregateDeclaration::getType()
535 {
536 return type;
537 }
538
isDeprecated()539 bool AggregateDeclaration::isDeprecated()
540 {
541 return isdeprecated;
542 }
543
isExport()544 bool AggregateDeclaration::isExport() const
545 {
546 return protection.kind == PROTexport;
547 }
548
549 /***************************************
550 * Calculate field[i].overlapped and overlapUnsafe, and check that all of explicit
551 * field initializers have unique memory space on instance.
552 * Returns:
553 * true if any errors happen.
554 */
555
checkOverlappedFields()556 bool AggregateDeclaration::checkOverlappedFields()
557 {
558 //printf("AggregateDeclaration::checkOverlappedFields() %s\n", toChars());
559 assert(sizeok == SIZEOKdone);
560 size_t nfields = fields.dim;
561 if (isNested())
562 {
563 ClassDeclaration *cd = isClassDeclaration();
564 if (!cd || !cd->baseClass || !cd->baseClass->isNested())
565 nfields--;
566 }
567 bool errors = false;
568
569 // Fill in missing any elements with default initializers
570 for (size_t i = 0; i < nfields; i++)
571 {
572 VarDeclaration *vd = fields[i];
573 if (vd->errors)
574 {
575 errors = true;
576 continue;
577 }
578
579 VarDeclaration *vx = vd;
580 if (vd->_init && vd->_init->isVoidInitializer())
581 vx = NULL;
582
583 // Find overlapped fields with the hole [vd->offset .. vd->offset->size()].
584 for (size_t j = 0; j < nfields; j++)
585 {
586 if (i == j)
587 continue;
588 VarDeclaration *v2 = fields[j];
589 if (v2->errors)
590 {
591 errors = true;
592 continue;
593 }
594 if (!vd->isOverlappedWith(v2))
595 continue;
596
597 // vd and v2 are overlapping.
598 vd->overlapped = true;
599 v2->overlapped = true;
600
601 if (!MODimplicitConv(vd->type->mod, v2->type->mod))
602 v2->overlapUnsafe = true;
603 if (!MODimplicitConv(v2->type->mod, vd->type->mod))
604 vd->overlapUnsafe = true;
605
606 if (!vx)
607 continue;
608 if (v2->_init && v2->_init->isVoidInitializer())
609 continue;
610
611 if (vx->_init && v2->_init)
612 {
613 ::error(loc, "overlapping default initialization for field %s and %s", v2->toChars(), vd->toChars());
614 errors = true;
615 }
616 }
617 }
618 return errors;
619 }
620
621 /***************************************
622 * Fill out remainder of elements[] with default initializers for fields[].
623 * Input:
624 * loc: location
625 * elements: explicit arguments which given to construct object.
626 * ctorinit: true if the elements will be used for default initialization.
627 * Returns:
628 * false if any errors occur.
629 * Otherwise, returns true and the missing arguments will be pushed in elements[].
630 */
fill(Loc loc,Expressions * elements,bool ctorinit)631 bool AggregateDeclaration::fill(Loc loc, Expressions *elements, bool ctorinit)
632 {
633 //printf("AggregateDeclaration::fill() %s\n", toChars());
634 assert(sizeok == SIZEOKdone);
635 assert(elements);
636 size_t nfields = fields.dim - isNested();
637 bool errors = false;
638
639 size_t dim = elements->dim;
640 elements->setDim(nfields);
641 for (size_t i = dim; i < nfields; i++)
642 (*elements)[i] = NULL;
643
644 // Fill in missing any elements with default initializers
645 for (size_t i = 0; i < nfields; i++)
646 {
647 if ((*elements)[i])
648 continue;
649
650 VarDeclaration *vd = fields[i];
651 VarDeclaration *vx = vd;
652 if (vd->_init && vd->_init->isVoidInitializer())
653 vx = NULL;
654
655 // Find overlapped fields with the hole [vd->offset .. vd->offset->size()].
656 size_t fieldi = i;
657 for (size_t j = 0; j < nfields; j++)
658 {
659 if (i == j)
660 continue;
661 VarDeclaration *v2 = fields[j];
662 if (!vd->isOverlappedWith(v2))
663 continue;
664
665 if ((*elements)[j])
666 {
667 vx = NULL;
668 break;
669 }
670 if (v2->_init && v2->_init->isVoidInitializer())
671 continue;
672
673 if (1)
674 {
675 /* Prefer first found non-void-initialized field
676 * union U { int a; int b = 2; }
677 * U u; // Error: overlapping initialization for field a and b
678 */
679 if (!vx)
680 {
681 vx = v2;
682 fieldi = j;
683 }
684 else if (v2->_init)
685 {
686 ::error(loc, "overlapping initialization for field %s and %s",
687 v2->toChars(), vd->toChars());
688 errors = true;
689 }
690 }
691 else
692 {
693 // Will fix Bugzilla 1432 by enabling this path always
694
695 /* Prefer explicitly initialized field
696 * union U { int a; int b = 2; }
697 * U u; // OK (u.b == 2)
698 */
699 if (!vx || (!vx->_init && v2->_init))
700 {
701 vx = v2;
702 fieldi = j;
703 }
704 else if (vx != vd && !vx->isOverlappedWith(v2))
705 {
706 // Both vx and v2 fills vd, but vx and v2 does not overlap
707 }
708 else if (vx->_init && v2->_init)
709 {
710 ::error(loc, "overlapping default initialization for field %s and %s",
711 v2->toChars(), vd->toChars());
712 errors = true;
713 }
714 else
715 assert(vx->_init || (!vx->_init && !v2->_init));
716 }
717 }
718 if (vx)
719 {
720 Expression *e;
721 if (vx->type->size() == 0)
722 {
723 e = NULL;
724 }
725 else if (vx->_init)
726 {
727 assert(!vx->_init->isVoidInitializer());
728 if (vx->inuse) // https://issues.dlang.org/show_bug.cgi?id=18057
729 {
730 vx->error(loc, "recursive initialization of field");
731 errors = true;
732 e = NULL;
733 }
734 else
735 e = vx->getConstInitializer(false);
736 }
737 else
738 {
739 if ((vx->storage_class & STCnodefaultctor) && !ctorinit)
740 {
741 ::error(loc, "field %s.%s must be initialized because it has no default constructor",
742 type->toChars(), vx->toChars());
743 errors = true;
744 }
745
746 /* Bugzilla 12509: Get the element of static array type.
747 */
748 Type *telem = vx->type;
749 if (telem->ty == Tsarray)
750 {
751 /* We cannot use Type::baseElemOf() here.
752 * If the bottom of the Tsarray is an enum type, baseElemOf()
753 * will return the base of the enum, and its default initializer
754 * would be different from the enum's.
755 */
756 while (telem->toBasetype()->ty == Tsarray)
757 telem = ((TypeSArray *)telem->toBasetype())->next;
758
759 if (telem->ty == Tvoid)
760 telem = Type::tuns8->addMod(telem->mod);
761 }
762 if (telem->needsNested() && ctorinit)
763 e = telem->defaultInit(loc);
764 else
765 e = telem->defaultInitLiteral(loc);
766 }
767 (*elements)[fieldi] = e;
768 }
769 }
770
771 for (size_t i = 0; i < elements->dim; i++)
772 {
773 Expression *e = (*elements)[i];
774 if (e && e->op == TOKerror)
775 return false;
776 }
777
778 return !errors;
779 }
780
781 /****************************
782 * Do byte or word alignment as necessary.
783 * Align sizes of 0, as we may not know array sizes yet.
784 *
785 * alignment: struct alignment that is in effect
786 * size: alignment requirement of field
787 */
788
alignmember(structalign_t alignment,unsigned size,unsigned * poffset)789 void AggregateDeclaration::alignmember(
790 structalign_t alignment,
791 unsigned size,
792 unsigned *poffset)
793 {
794 //printf("alignment = %d, size = %d, offset = %d\n",alignment,size,offset);
795 switch (alignment)
796 {
797 case (structalign_t) 1:
798 // No alignment
799 break;
800
801 case (structalign_t) STRUCTALIGN_DEFAULT:
802 // Alignment in Target::fieldalignsize must match what the
803 // corresponding C compiler's default alignment behavior is.
804 assert(size > 0 && !(size & (size - 1)));
805 *poffset = (*poffset + size - 1) & ~(size - 1);
806 break;
807
808 default:
809 // Align on alignment boundary, which must be a positive power of 2
810 assert(alignment > 0 && !(alignment & (alignment - 1)));
811 *poffset = (*poffset + alignment - 1) & ~(alignment - 1);
812 break;
813 }
814 }
815
816 /****************************************
817 * Place a member (mem) into an aggregate (agg), which can be a struct, union or class
818 * Returns:
819 * offset to place field at
820 *
821 * nextoffset: next location in aggregate
822 * memsize: size of member
823 * memalignsize: natural alignment of member
824 * alignment: alignment in effect for this member
825 * paggsize: size of aggregate (updated)
826 * paggalignsize: alignment of aggregate (updated)
827 * isunion: the aggregate is a union
828 */
placeField(unsigned * nextoffset,unsigned memsize,unsigned memalignsize,structalign_t alignment,unsigned * paggsize,unsigned * paggalignsize,bool isunion)829 unsigned AggregateDeclaration::placeField(
830 unsigned *nextoffset,
831 unsigned memsize,
832 unsigned memalignsize,
833 structalign_t alignment,
834 unsigned *paggsize,
835 unsigned *paggalignsize,
836 bool isunion
837 )
838 {
839 unsigned ofs = *nextoffset;
840
841 const unsigned actualAlignment =
842 alignment == STRUCTALIGN_DEFAULT ? memalignsize : alignment;
843
844 alignmember(alignment, memalignsize, &ofs);
845 unsigned memoffset = ofs;
846 ofs += memsize;
847 if (ofs > *paggsize)
848 *paggsize = ofs;
849 if (!isunion)
850 *nextoffset = ofs;
851
852 if (*paggalignsize < actualAlignment)
853 *paggalignsize = actualAlignment;
854
855 return memoffset;
856 }
857
858
859 /****************************************
860 * Returns true if there's an extra member which is the 'this'
861 * pointer to the enclosing context (enclosing aggregate or function)
862 */
863
isNested()864 bool AggregateDeclaration::isNested()
865 {
866 return enclosing != NULL;
867 }
868
869 /* Append vthis field (this->tupleof[$-1]) to make this aggregate type nested.
870 */
makeNested()871 void AggregateDeclaration::makeNested()
872 {
873 if (enclosing) // if already nested
874 return;
875 if (sizeok == SIZEOKdone)
876 return;
877 if (isUnionDeclaration() || isInterfaceDeclaration())
878 return;
879 if (storage_class & STCstatic)
880 return;
881
882 // If nested struct, add in hidden 'this' pointer to outer scope
883 Dsymbol *s = toParent2();
884 if (!s)
885 return;
886 Type *t = NULL;
887 if (FuncDeclaration *fd = s->isFuncDeclaration())
888 {
889 enclosing = fd;
890
891 /* Bugzilla 14422: If a nested class parent is a function, its
892 * context pointer (== `outer`) should be void* always.
893 */
894 t = Type::tvoidptr;
895 }
896 else if (AggregateDeclaration *ad = s->isAggregateDeclaration())
897 {
898 if (isClassDeclaration() && ad->isClassDeclaration())
899 {
900 enclosing = ad;
901 }
902 else if (isStructDeclaration())
903 {
904 if (TemplateInstance *ti = ad->parent->isTemplateInstance())
905 {
906 enclosing = ti->enclosing;
907 }
908 }
909
910 t = ad->handleType();
911 }
912 if (enclosing)
913 {
914 //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars());
915 assert(t);
916 if (t->ty == Tstruct)
917 t = Type::tvoidptr; // t should not be a ref type
918 assert(!vthis);
919 vthis = new ThisDeclaration(loc, t);
920 //vthis->storage_class |= STCref;
921
922 // Emulate vthis->addMember()
923 members->push(vthis);
924
925 // Emulate vthis->semantic()
926 vthis->storage_class |= STCfield;
927 vthis->parent = this;
928 vthis->protection = Prot(PROTpublic);
929 vthis->alignment = t->alignment();
930 vthis->semanticRun = PASSsemanticdone;
931
932 if (sizeok == SIZEOKfwd)
933 fields.push(vthis);
934 }
935 }
936
937 /*******************************************
938 * Look for constructor declaration.
939 */
searchCtor()940 Dsymbol *AggregateDeclaration::searchCtor()
941 {
942 Dsymbol *s = search(Loc(), Id::ctor);
943 if (s)
944 {
945 if (!(s->isCtorDeclaration() ||
946 s->isTemplateDeclaration() ||
947 s->isOverloadSet()))
948 {
949 s->error("is not a constructor; identifiers starting with __ are reserved for the implementation");
950 errors = true;
951 s = NULL;
952 }
953 }
954 if (s && s->toParent() != this)
955 s = NULL; // search() looks through ancestor classes
956 if (s)
957 {
958 // Finish all constructors semantics to determine this->noDefaultCtor.
959 struct SearchCtor
960 {
961 static int fp(Dsymbol *s, void *)
962 {
963 CtorDeclaration *f = s->isCtorDeclaration();
964 if (f && f->semanticRun == PASSinit)
965 f->semantic(NULL);
966 return 0;
967 }
968 };
969
970 for (size_t i = 0; i < members->dim; i++)
971 {
972 Dsymbol *sm = (*members)[i];
973 sm->apply(&SearchCtor::fp, NULL);
974 }
975 }
976 return s;
977 }
978
979 /********************************* StructDeclaration ****************************/
980
StructDeclaration(Loc loc,Identifier * id,bool inObject)981 StructDeclaration::StructDeclaration(Loc loc, Identifier *id, bool inObject)
982 : AggregateDeclaration(loc, id)
983 {
984 zeroInit = 0; // assume false until we do semantic processing
985 hasIdentityAssign = false;
986 hasIdentityEquals = false;
987 postblit = NULL;
988
989 xeq = NULL;
990 xcmp = NULL;
991 xhash = NULL;
992 alignment = 0;
993 ispod = ISPODfwd;
994 arg1type = NULL;
995 arg2type = NULL;
996 requestTypeInfo = false;
997
998 // For forward references
999 type = new TypeStruct(this);
1000
1001 if (inObject)
1002 {
1003 if (id == Id::ModuleInfo && !Module::moduleinfo)
1004 Module::moduleinfo = this;
1005 }
1006 }
1007
create(Loc loc,Identifier * id,bool inObject)1008 StructDeclaration *StructDeclaration::create(Loc loc, Identifier *id, bool inObject)
1009 {
1010 return new StructDeclaration(loc, id, inObject);
1011 }
1012
syntaxCopy(Dsymbol * s)1013 Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
1014 {
1015 StructDeclaration *sd =
1016 s ? (StructDeclaration *)s
1017 : new StructDeclaration(loc, ident, false);
1018 return ScopeDsymbol::syntaxCopy(sd);
1019 }
1020
semantic(Scope * sc)1021 void StructDeclaration::semantic(Scope *sc)
1022 {
1023 //printf("StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok);
1024
1025 //static int count; if (++count == 20) halt();
1026
1027 if (semanticRun >= PASSsemanticdone)
1028 return;
1029 unsigned errors = global.errors;
1030
1031 //printf("+StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok);
1032 Scope *scx = NULL;
1033 if (_scope)
1034 {
1035 sc = _scope;
1036 scx = _scope; // save so we don't make redundant copies
1037 _scope = NULL;
1038 }
1039
1040 if (!parent)
1041 {
1042 assert(sc->parent && sc->func);
1043 parent = sc->parent;
1044 }
1045 assert(parent && !isAnonymous());
1046
1047 if (this->errors)
1048 type = Type::terror;
1049 if (semanticRun == PASSinit)
1050 type = type->addSTC(sc->stc | storage_class);
1051 type = type->semantic(loc, sc);
1052
1053 if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this)
1054 {
1055 TemplateInstance *ti = ((TypeStruct *)type)->sym->isInstantiated();
1056 if (ti && isError(ti))
1057 ((TypeStruct *)type)->sym = this;
1058 }
1059
1060 // Ungag errors when not speculative
1061 Ungag ungag = ungagSpeculative();
1062
1063 if (semanticRun == PASSinit)
1064 {
1065 protection = sc->protection;
1066
1067 alignment = sc->alignment();
1068
1069 storage_class |= sc->stc;
1070 if (storage_class & STCdeprecated)
1071 isdeprecated = true;
1072 if (storage_class & STCabstract)
1073 error("structs, unions cannot be abstract");
1074 userAttribDecl = sc->userAttribDecl;
1075
1076 if (sc->linkage == LINKcpp)
1077 classKind = ClassKind::cpp;
1078 }
1079 else if (symtab && !scx)
1080 {
1081 return;
1082 }
1083 semanticRun = PASSsemantic;
1084
1085 if (!members) // if opaque declaration
1086 {
1087 semanticRun = PASSsemanticdone;
1088 return;
1089 }
1090 if (!symtab)
1091 {
1092 symtab = new DsymbolTable();
1093
1094 for (size_t i = 0; i < members->dim; i++)
1095 {
1096 Dsymbol *s = (*members)[i];
1097 //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
1098 s->addMember(sc, this);
1099 }
1100 }
1101
1102 Scope *sc2 = newScope(sc);
1103
1104 /* Set scope so if there are forward references, we still might be able to
1105 * resolve individual members like enums.
1106 */
1107 for (size_t i = 0; i < members->dim; i++)
1108 {
1109 Dsymbol *s = (*members)[i];
1110 //printf("struct: setScope %s %s\n", s->kind(), s->toChars());
1111 s->setScope(sc2);
1112 }
1113
1114 for (size_t i = 0; i < members->dim; i++)
1115 {
1116 Dsymbol *s = (*members)[i];
1117 s->importAll(sc2);
1118 }
1119
1120 for (size_t i = 0; i < members->dim; i++)
1121 {
1122 Dsymbol *s = (*members)[i];
1123 s->semantic(sc2);
1124 }
1125
1126 if (!determineFields())
1127 {
1128 assert(type->ty == Terror);
1129 sc2->pop();
1130 semanticRun = PASSsemanticdone;
1131 return;
1132 }
1133
1134 /* Following special member functions creation needs semantic analysis
1135 * completion of sub-structs in each field types. For example, buildDtor
1136 * needs to check existence of elaborate dtor in type of each fields.
1137 * See the case in compilable/test14838.d
1138 */
1139 for (size_t i = 0; i < fields.dim; i++)
1140 {
1141 VarDeclaration *v = fields[i];
1142 Type *tb = v->type->baseElemOf();
1143 if (tb->ty != Tstruct)
1144 continue;
1145 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
1146 if (sd->semanticRun >= PASSsemanticdone)
1147 continue;
1148
1149 sc2->pop();
1150
1151 _scope = scx ? scx : sc->copy();
1152 _scope->setNoFree();
1153 _scope->_module->addDeferredSemantic(this);
1154
1155 //printf("\tdeferring %s\n", toChars());
1156 return;
1157 }
1158
1159 /* Look for special member functions.
1160 */
1161 aggNew = (NewDeclaration *)search(Loc(), Id::classNew);
1162 aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);
1163
1164 // Look for the constructor
1165 ctor = searchCtor();
1166
1167 dtor = buildDtor(this, sc2);
1168 postblit = buildPostBlit(this, sc2);
1169
1170 buildOpAssign(this, sc2);
1171 buildOpEquals(this, sc2);
1172
1173 if (global.params.useTypeInfo && Type::dtypeinfo) // these functions are used for TypeInfo
1174 {
1175 xeq = buildXopEquals(this, sc2);
1176 xcmp = buildXopCmp(this, sc2);
1177 xhash = buildXtoHash(this, sc2);
1178 }
1179
1180 inv = buildInv(this, sc2);
1181
1182 Module::dprogress++;
1183 semanticRun = PASSsemanticdone;
1184 //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
1185
1186 sc2->pop();
1187
1188 if (ctor)
1189 {
1190 Dsymbol *scall = search(Loc(), Id::call);
1191 if (scall)
1192 {
1193 unsigned xerrors = global.startGagging();
1194 sc = sc->push();
1195 sc->tinst = NULL;
1196 sc->minst = NULL;
1197 FuncDeclaration *fcall = resolveFuncCall(loc, sc, scall, NULL, NULL, NULL, 1);
1198 sc = sc->pop();
1199 global.endGagging(xerrors);
1200
1201 if (fcall && fcall->isStatic())
1202 {
1203 error(fcall->loc, "static opCall is hidden by constructors and can never be called");
1204 errorSupplemental(fcall->loc, "Please use a factory method instead, or replace all constructors with static opCall.");
1205 }
1206 }
1207 }
1208
1209 if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this)
1210 {
1211 // https://issues.dlang.org/show_bug.cgi?id=19024
1212 StructDeclaration *sd = ((TypeStruct *)type)->sym;
1213 error("already exists at %s. Perhaps in another function with the same name?", sd->loc.toChars());
1214 }
1215
1216 if (global.errors != errors)
1217 {
1218 // The type is no good.
1219 type = Type::terror;
1220 this->errors = true;
1221 if (deferred)
1222 deferred->errors = true;
1223 }
1224
1225 if (deferred && !global.gag)
1226 {
1227 deferred->semantic2(sc);
1228 deferred->semantic3(sc);
1229 }
1230 }
1231
search(const Loc & loc,Identifier * ident,int flags)1232 Dsymbol *StructDeclaration::search(const Loc &loc, Identifier *ident, int flags)
1233 {
1234 //printf("%s.StructDeclaration::search('%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
1235
1236 if (_scope && !symtab)
1237 semantic(_scope);
1238
1239 if (!members || !symtab) // opaque or semantic() is not yet called
1240 {
1241 error("is forward referenced when looking for '%s'", ident->toChars());
1242 return NULL;
1243 }
1244
1245 return ScopeDsymbol::search(loc, ident, flags);
1246 }
1247
finalizeSize()1248 void StructDeclaration::finalizeSize()
1249 {
1250 //printf("StructDeclaration::finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
1251 assert(sizeok != SIZEOKdone);
1252
1253 //printf("+StructDeclaration::finalizeSize() %s, fields.dim = %d, sizeok = %d\n", toChars(), fields.dim, sizeok);
1254
1255 fields.setDim(0); // workaround
1256
1257 // Set the offsets of the fields and determine the size of the struct
1258 unsigned offset = 0;
1259 bool isunion = isUnionDeclaration() != NULL;
1260 for (size_t i = 0; i < members->dim; i++)
1261 {
1262 Dsymbol *s = (*members)[i];
1263 s->setFieldOffset(this, &offset, isunion);
1264 }
1265 if (type->ty == Terror)
1266 return;
1267
1268 // 0 sized struct's are set to 1 byte
1269 if (structsize == 0)
1270 {
1271 structsize = 1;
1272 alignsize = 1;
1273 }
1274
1275 // Round struct size up to next alignsize boundary.
1276 // This will ensure that arrays of structs will get their internals
1277 // aligned properly.
1278 if (alignment == STRUCTALIGN_DEFAULT)
1279 structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
1280 else
1281 structsize = (structsize + alignment - 1) & ~(alignment - 1);
1282
1283 sizeok = SIZEOKdone;
1284
1285 //printf("-StructDeclaration::finalizeSize() %s, fields.dim = %d, structsize = %d\n", toChars(), fields.dim, structsize);
1286
1287 if (errors)
1288 return;
1289
1290 // Calculate fields[i]->overlapped
1291 if (checkOverlappedFields())
1292 {
1293 errors = true;
1294 return;
1295 }
1296
1297 // Determine if struct is all zeros or not
1298 zeroInit = 1;
1299 for (size_t i = 0; i < fields.dim; i++)
1300 {
1301 VarDeclaration *vd = fields[i];
1302 if (vd->_init)
1303 {
1304 // Should examine init to see if it is really all 0's
1305 zeroInit = 0;
1306 break;
1307 }
1308 else if (!vd->type->isZeroInit(loc))
1309 {
1310 zeroInit = 0;
1311 break;
1312 }
1313 }
1314
1315 TypeTuple *tt = Target::toArgTypes(type);
1316 size_t dim = tt ? tt->arguments->dim : 0;
1317 if (dim >= 1)
1318 {
1319 assert(dim <= 2);
1320 arg1type = (*tt->arguments)[0]->type;
1321 if (dim == 2)
1322 arg2type = (*tt->arguments)[1]->type;
1323 }
1324 }
1325
1326 /***************************************
1327 * Fit elements[] to the corresponding type of field[].
1328 * Input:
1329 * loc
1330 * sc
1331 * elements The explicit arguments that given to construct object.
1332 * stype The constructed object type.
1333 * Returns false if any errors occur.
1334 * Otherwise, returns true and elements[] are rewritten for the output.
1335 */
fit(Loc loc,Scope * sc,Expressions * elements,Type * stype)1336 bool StructDeclaration::fit(Loc loc, Scope *sc, Expressions *elements, Type *stype)
1337 {
1338 if (!elements)
1339 return true;
1340
1341 size_t nfields = fields.dim - isNested();
1342 size_t offset = 0;
1343 for (size_t i = 0; i < elements->dim; i++)
1344 {
1345 Expression *e = (*elements)[i];
1346 if (!e)
1347 continue;
1348
1349 e = resolveProperties(sc, e);
1350 if (i >= nfields)
1351 {
1352 if (i == fields.dim - 1 && isNested() && e->op == TOKnull)
1353 {
1354 // CTFE sometimes creates null as hidden pointer; we'll allow this.
1355 continue;
1356 }
1357 ::error(loc, "more initializers than fields (%d) of %s", (int)nfields, toChars());
1358 return false;
1359 }
1360 VarDeclaration *v = fields[i];
1361 if (v->offset < offset)
1362 {
1363 ::error(loc, "overlapping initialization for %s", v->toChars());
1364 return false;
1365 }
1366 offset = (unsigned)(v->offset + v->type->size());
1367
1368 Type *t = v->type;
1369 if (stype)
1370 t = t->addMod(stype->mod);
1371 Type *origType = t;
1372 Type *tb = t->toBasetype();
1373
1374 /* Look for case of initializing a static array with a too-short
1375 * string literal, such as:
1376 * char[5] foo = "abc";
1377 * Allow this by doing an explicit cast, which will lengthen the string
1378 * literal.
1379 */
1380 if (e->op == TOKstring && tb->ty == Tsarray)
1381 {
1382 StringExp *se = (StringExp *)e;
1383 Type *typeb = se->type->toBasetype();
1384 TY tynto = tb->nextOf()->ty;
1385 if (!se->committed &&
1386 (typeb->ty == Tarray || typeb->ty == Tsarray) &&
1387 (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&
1388 se->numberOfCodeUnits(tynto) < ((TypeSArray *)tb)->dim->toInteger())
1389 {
1390 e = se->castTo(sc, t);
1391 goto L1;
1392 }
1393 }
1394
1395 while (!e->implicitConvTo(t) && tb->ty == Tsarray)
1396 {
1397 /* Static array initialization, as in:
1398 * T[3][5] = e;
1399 */
1400 t = tb->nextOf();
1401 tb = t->toBasetype();
1402 }
1403 if (!e->implicitConvTo(t))
1404 t = origType; // restore type for better diagnostic
1405
1406 e = e->implicitCastTo(sc, t);
1407 L1:
1408 if (e->op == TOKerror)
1409 return false;
1410
1411 (*elements)[i] = doCopyOrMove(sc, e);
1412 }
1413 return true;
1414 }
1415
1416 /***************************************
1417 * Return true if struct is POD (Plain Old Data).
1418 * This is defined as:
1419 * not nested
1420 * no postblits, destructors, or assignment operators
1421 * no 'ref' fields or fields that are themselves non-POD
1422 * The idea being these are compatible with C structs.
1423 */
isPOD()1424 bool StructDeclaration::isPOD()
1425 {
1426 // If we've already determined whether this struct is POD.
1427 if (ispod != ISPODfwd)
1428 return (ispod == ISPODyes);
1429
1430 ispod = ISPODyes;
1431
1432 if (enclosing || postblit || dtor)
1433 ispod = ISPODno;
1434
1435 // Recursively check all fields are POD.
1436 for (size_t i = 0; i < fields.dim; i++)
1437 {
1438 VarDeclaration *v = fields[i];
1439 if (v->storage_class & STCref)
1440 {
1441 ispod = ISPODno;
1442 break;
1443 }
1444
1445 Type *tv = v->type->baseElemOf();
1446 if (tv->ty == Tstruct)
1447 {
1448 TypeStruct *ts = (TypeStruct *)tv;
1449 StructDeclaration *sd = ts->sym;
1450 if (!sd->isPOD())
1451 {
1452 ispod = ISPODno;
1453 break;
1454 }
1455 }
1456 }
1457
1458 return (ispod == ISPODyes);
1459 }
1460
kind()1461 const char *StructDeclaration::kind() const
1462 {
1463 return "struct";
1464 }
1465
1466 /********************************* UnionDeclaration ****************************/
1467
UnionDeclaration(Loc loc,Identifier * id)1468 UnionDeclaration::UnionDeclaration(Loc loc, Identifier *id)
1469 : StructDeclaration(loc, id, false)
1470 {
1471 }
1472
syntaxCopy(Dsymbol * s)1473 Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s)
1474 {
1475 assert(!s);
1476 UnionDeclaration *ud = new UnionDeclaration(loc, ident);
1477 return StructDeclaration::syntaxCopy(ud);
1478 }
1479
kind()1480 const char *UnionDeclaration::kind() const
1481 {
1482 return "union";
1483 }
1484