xref: /netbsd/external/gpl3/gcc/dist/gcc/d/dmd/dstruct.c (revision ed2d4fca)
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