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