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