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/attrib.c
9  */
10 
11 #include "root/dsystem.h"               // memcmp()
12 #include "root/rmem.h"
13 
14 #include "mars.h"
15 #include "init.h"
16 #include "declaration.h"
17 #include "attrib.h"
18 #include "cond.h"
19 #include "scope.h"
20 #include "id.h"
21 #include "expression.h"
22 #include "dsymbol.h"
23 #include "aggregate.h"
24 #include "module.h"
25 #include "parse.h"
26 #include "target.h"
27 #include "template.h"
28 #include "utf.h"
29 #include "mtype.h"
30 
31 bool definitelyValueParameter(Expression *e);
32 Expression *semantic(Expression *e, Scope *sc);
33 StringExp *semanticString(Scope *sc, Expression *exp, const char *s);
34 
35 /********************************* AttribDeclaration ****************************/
36 
AttribDeclaration(Dsymbols * decl)37 AttribDeclaration::AttribDeclaration(Dsymbols *decl)
38         : Dsymbol()
39 {
40     this->decl = decl;
41 }
42 
include(Scope *,ScopeDsymbol *)43 Dsymbols *AttribDeclaration::include(Scope *, ScopeDsymbol *)
44 {
45     return decl;
46 }
47 
apply(Dsymbol_apply_ft_t fp,void * param)48 int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param)
49 {
50     Dsymbols *d = include(_scope, NULL);
51 
52     if (d)
53     {
54         for (size_t i = 0; i < d->dim; i++)
55         {
56             Dsymbol *s = (*d)[i];
57             if (s)
58             {
59                 if (s->apply(fp, param))
60                     return 1;
61             }
62         }
63     }
64     return 0;
65 }
66 
67 /****************************************
68  * Create a new scope if one or more given attributes
69  * are different from the sc's.
70  * If the returned scope != sc, the caller should pop
71  * the scope after it used.
72  */
createNewScope(Scope * sc,StorageClass stc,LINK linkage,CPPMANGLE cppmangle,Prot protection,int explicitProtection,AlignDeclaration * aligndecl,PINLINE inlining)73 Scope *AttribDeclaration::createNewScope(Scope *sc,
74         StorageClass stc, LINK linkage, CPPMANGLE cppmangle, Prot protection,
75         int explicitProtection, AlignDeclaration *aligndecl, PINLINE inlining)
76 {
77     Scope *sc2 = sc;
78     if (stc != sc->stc ||
79         linkage != sc->linkage ||
80         cppmangle != sc->cppmangle ||
81         !protection.isSubsetOf(sc->protection) ||
82         explicitProtection != sc->explicitProtection ||
83         aligndecl != sc->aligndecl ||
84         inlining != sc->inlining)
85     {
86         // create new one for changes
87         sc2 = sc->copy();
88         sc2->stc = stc;
89         sc2->linkage = linkage;
90         sc2->cppmangle = cppmangle;
91         sc2->protection = protection;
92         sc2->explicitProtection = explicitProtection;
93         sc2->aligndecl = aligndecl;
94         sc2->inlining = inlining;
95     }
96     return sc2;
97 }
98 
99 /****************************************
100  * A hook point to supply scope for members.
101  * addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this.
102  */
newScope(Scope * sc)103 Scope *AttribDeclaration::newScope(Scope *sc)
104 {
105     return sc;
106 }
107 
addMember(Scope * sc,ScopeDsymbol * sds)108 void AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
109 {
110     Dsymbols *d = include(sc, sds);
111 
112     if (d)
113     {
114         Scope *sc2 = newScope(sc);
115 
116         for (size_t i = 0; i < d->dim; i++)
117         {
118             Dsymbol *s = (*d)[i];
119             //printf("\taddMember %s to %s\n", s->toChars(), sds->toChars());
120             s->addMember(sc2, sds);
121         }
122 
123         if (sc2 != sc)
124             sc2->pop();
125     }
126 }
127 
setScope(Scope * sc)128 void AttribDeclaration::setScope(Scope *sc)
129 {
130     Dsymbols *d = include(sc, NULL);
131 
132     //printf("\tAttribDeclaration::setScope '%s', d = %p\n",toChars(), d);
133     if (d)
134     {
135         Scope *sc2 = newScope(sc);
136 
137         for (size_t i = 0; i < d->dim; i++)
138         {
139             Dsymbol *s = (*d)[i];
140             s->setScope(sc2);
141         }
142 
143         if (sc2 != sc)
144             sc2->pop();
145     }
146 }
147 
importAll(Scope * sc)148 void AttribDeclaration::importAll(Scope *sc)
149 {
150     Dsymbols *d = include(sc, NULL);
151 
152     //printf("\tAttribDeclaration::importAll '%s', d = %p\n", toChars(), d);
153     if (d)
154     {
155         Scope *sc2 = newScope(sc);
156 
157         for (size_t i = 0; i < d->dim; i++)
158         {
159             Dsymbol *s = (*d)[i];
160             s->importAll(sc2);
161         }
162 
163         if (sc2 != sc)
164             sc2->pop();
165     }
166 }
167 
semantic(Scope * sc)168 void AttribDeclaration::semantic(Scope *sc)
169 {
170     if (semanticRun != PASSinit)
171         return;
172     semanticRun = PASSsemantic;
173     Dsymbols *d = include(sc, NULL);
174 
175     //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
176     if (d)
177     {
178         Scope *sc2 = newScope(sc);
179 
180         for (size_t i = 0; i < d->dim; i++)
181         {
182             Dsymbol *s = (*d)[i];
183             s->semantic(sc2);
184         }
185 
186         if (sc2 != sc)
187             sc2->pop();
188     }
189     semanticRun = PASSsemanticdone;
190 }
191 
semantic2(Scope * sc)192 void AttribDeclaration::semantic2(Scope *sc)
193 {
194     Dsymbols *d = include(sc, NULL);
195 
196     if (d)
197     {
198         Scope *sc2 = newScope(sc);
199 
200         for (size_t i = 0; i < d->dim; i++)
201         {
202             Dsymbol *s = (*d)[i];
203             s->semantic2(sc2);
204         }
205 
206         if (sc2 != sc)
207             sc2->pop();
208     }
209 }
210 
semantic3(Scope * sc)211 void AttribDeclaration::semantic3(Scope *sc)
212 {
213     Dsymbols *d = include(sc, NULL);
214 
215     if (d)
216     {
217         Scope *sc2 = newScope(sc);
218 
219         for (size_t i = 0; i < d->dim; i++)
220         {
221             Dsymbol *s = (*d)[i];
222             s->semantic3(sc2);
223         }
224 
225         if (sc2 != sc)
226             sc2->pop();
227     }
228 }
229 
addComment(const utf8_t * comment)230 void AttribDeclaration::addComment(const utf8_t *comment)
231 {
232     //printf("AttribDeclaration::addComment %s\n", comment);
233     if (comment)
234     {
235         Dsymbols *d = include(NULL, NULL);
236 
237         if (d)
238         {
239             for (size_t i = 0; i < d->dim; i++)
240             {
241                 Dsymbol *s = (*d)[i];
242                 //printf("AttribDeclaration::addComment %s\n", s->toChars());
243                 s->addComment(comment);
244             }
245         }
246     }
247 }
248 
setFieldOffset(AggregateDeclaration * ad,unsigned * poffset,bool isunion)249 void AttribDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
250 {
251     Dsymbols *d = include(NULL, NULL);
252 
253     if (d)
254     {
255         for (size_t i = 0; i < d->dim; i++)
256         {
257             Dsymbol *s = (*d)[i];
258             s->setFieldOffset(ad, poffset, isunion);
259         }
260     }
261 }
262 
hasPointers()263 bool AttribDeclaration::hasPointers()
264 {
265     Dsymbols *d = include(NULL, NULL);
266 
267     if (d)
268     {
269         for (size_t i = 0; i < d->dim; i++)
270         {
271             Dsymbol *s = (*d)[i];
272             if (s->hasPointers())
273                 return true;
274         }
275     }
276     return false;
277 }
278 
hasStaticCtorOrDtor()279 bool AttribDeclaration::hasStaticCtorOrDtor()
280 {
281     Dsymbols *d = include(NULL, NULL);
282 
283     if (d)
284     {
285         for (size_t i = 0; i < d->dim; i++)
286         {
287             Dsymbol *s = (*d)[i];
288             if (s->hasStaticCtorOrDtor())
289                 return true;
290         }
291     }
292     return false;
293 }
294 
kind()295 const char *AttribDeclaration::kind() const
296 {
297     return "attribute";
298 }
299 
oneMember(Dsymbol ** ps,Identifier * ident)300 bool AttribDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
301 {
302     Dsymbols *d = include(NULL, NULL);
303 
304     return Dsymbol::oneMembers(d, ps, ident);
305 }
306 
checkCtorConstInit()307 void AttribDeclaration::checkCtorConstInit()
308 {
309     Dsymbols *d = include(NULL, NULL);
310 
311     if (d)
312     {
313         for (size_t i = 0; i < d->dim; i++)
314         {
315             Dsymbol *s = (*d)[i];
316             s->checkCtorConstInit();
317         }
318     }
319 }
320 
321 /****************************************
322  */
323 
addLocalClass(ClassDeclarations * aclasses)324 void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
325 {
326     Dsymbols *d = include(NULL, NULL);
327 
328     if (d)
329     {
330         for (size_t i = 0; i < d->dim; i++)
331         {
332             Dsymbol *s = (*d)[i];
333             s->addLocalClass(aclasses);
334         }
335     }
336 }
337 
338 /************************* StorageClassDeclaration ****************************/
339 
StorageClassDeclaration(StorageClass stc,Dsymbols * decl)340 StorageClassDeclaration::StorageClassDeclaration(StorageClass stc, Dsymbols *decl)
341         : AttribDeclaration(decl)
342 {
343     this->stc = stc;
344 }
345 
syntaxCopy(Dsymbol * s)346 Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s)
347 {
348     assert(!s);
349     return new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl));
350 }
351 
oneMember(Dsymbol ** ps,Identifier * ident)352 bool StorageClassDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
353 {
354     bool t = Dsymbol::oneMembers(decl, ps, ident);
355     if (t && *ps)
356     {
357         /* This is to deal with the following case:
358          * struct Tick {
359          *   template to(T) { const T to() { ... } }
360          * }
361          * For eponymous function templates, the 'const' needs to get attached to 'to'
362          * before the semantic analysis of 'to', so that template overloading based on the
363          * 'this' pointer can be successful.
364          */
365 
366         FuncDeclaration *fd = (*ps)->isFuncDeclaration();
367         if (fd)
368         {
369             /* Use storage_class2 instead of storage_class otherwise when we do .di generation
370              * we'll wind up with 'const const' rather than 'const'.
371              */
372             /* Don't think we need to worry about mutually exclusive storage classes here
373              */
374             fd->storage_class2 |= stc;
375         }
376     }
377     return t;
378 }
379 
addMember(Scope * sc,ScopeDsymbol * sds)380 void StorageClassDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
381 {
382     Dsymbols *d = include(sc, sds);
383     if (d)
384     {
385         Scope *sc2 = newScope(sc);
386         for (size_t i = 0; i < d->dim; i++)
387         {
388             Dsymbol *s = (*d)[i];
389             //printf("\taddMember %s to %s\n", s->toChars(), sds->toChars());
390             // STClocal needs to be attached before the member is added to the scope (because it influences the parent symbol)
391             if (Declaration *decl = s->isDeclaration())
392             {
393                 decl->storage_class |= stc & STClocal;
394                 if (StorageClassDeclaration *sdecl = s->isStorageClassDeclaration())
395                 {
396                     sdecl->stc |= stc & STClocal;
397                 }
398             }
399             s->addMember(sc2, sds);
400         }
401         if (sc2 != sc)
402             sc2->pop();
403     }
404 }
405 
newScope(Scope * sc)406 Scope *StorageClassDeclaration::newScope(Scope *sc)
407 {
408     StorageClass scstc = sc->stc;
409 
410     /* These sets of storage classes are mutually exclusive,
411      * so choose the innermost or most recent one.
412      */
413     if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest))
414         scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest);
415     if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared))
416         scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared);
417     if (stc & (STCconst | STCimmutable | STCmanifest))
418         scstc &= ~(STCconst | STCimmutable | STCmanifest);
419     if (stc & (STCgshared | STCshared | STCtls))
420         scstc &= ~(STCgshared | STCshared | STCtls);
421     if (stc & (STCsafe | STCtrusted | STCsystem))
422         scstc &= ~(STCsafe | STCtrusted | STCsystem);
423     scstc |= stc;
424     //printf("scstc = x%llx\n", scstc);
425 
426     return createNewScope(sc, scstc, sc->linkage, sc->cppmangle,
427         sc->protection, sc->explicitProtection, sc->aligndecl,
428         sc->inlining);
429 }
430 
431 /********************************* DeprecatedDeclaration ****************************/
432 
DeprecatedDeclaration(Expression * msg,Dsymbols * decl)433 DeprecatedDeclaration::DeprecatedDeclaration(Expression *msg, Dsymbols *decl)
434         : StorageClassDeclaration(STCdeprecated, decl)
435 {
436     this->msg = msg;
437     this->msgstr = NULL;
438 }
439 
syntaxCopy(Dsymbol * s)440 Dsymbol *DeprecatedDeclaration::syntaxCopy(Dsymbol *s)
441 {
442     assert(!s);
443     return new DeprecatedDeclaration(msg->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl));
444 }
445 
446 /**
447  * Provides a new scope with `STCdeprecated` and `Scope.depdecl` set
448  *
449  * Calls `StorageClassDeclaration.newScope` (as it must be called or copied
450  * in any function overriding `newScope`), then set the `Scope`'s depdecl.
451  *
452  * Returns:
453  *   Always a new scope, to use for this `DeprecatedDeclaration`'s members.
454  */
newScope(Scope * sc)455 Scope *DeprecatedDeclaration::newScope(Scope *sc)
456 {
457     Scope *scx = StorageClassDeclaration::newScope(sc);
458     // The enclosing scope is deprecated as well
459     if (scx == sc)
460         scx = sc->push();
461     scx->depdecl = this;
462     return scx;
463 }
464 
setScope(Scope * sc)465 void DeprecatedDeclaration::setScope(Scope *sc)
466 {
467     //printf("DeprecatedDeclaration::setScope() %p\n", this);
468     if (decl)
469         Dsymbol::setScope(sc); // for forward reference
470     return AttribDeclaration::setScope(sc);
471 }
472 
473 /**
474  * Run the DeprecatedDeclaration's semantic2 phase then its members.
475  *
476  * The message set via a `DeprecatedDeclaration` can be either of:
477  * - a string literal
478  * - an enum
479  * - a static immutable
480  * So we need to call ctfe to resolve it.
481  * Afterward forwards to the members' semantic2.
482  */
semantic2(Scope * sc)483 void DeprecatedDeclaration::semantic2(Scope *sc)
484 {
485     getMessage();
486     StorageClassDeclaration::semantic2(sc);
487 }
488 
getMessage()489 const char *DeprecatedDeclaration::getMessage()
490 {
491     if (Scope *sc = _scope)
492     {
493         _scope = NULL;
494 
495         sc = sc->startCTFE();
496         msg = ::semantic(msg, sc);
497         msg = resolveProperties(sc, msg);
498         sc = sc->endCTFE();
499         msg = msg->ctfeInterpret();
500 
501         if (StringExp *se = msg->toStringExp())
502             msgstr = (char *)se->string;
503         else
504             msg->error("compile time constant expected, not '%s'", msg->toChars());
505     }
506     return msgstr;
507 }
508 
509 /********************************* LinkDeclaration ****************************/
510 
LinkDeclaration(LINK p,Dsymbols * decl)511 LinkDeclaration::LinkDeclaration(LINK p, Dsymbols *decl)
512         : AttribDeclaration(decl)
513 {
514     //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
515     linkage = (p == LINKsystem) ? Target::systemLinkage() : p;
516 }
517 
create(LINK p,Dsymbols * decl)518 LinkDeclaration *LinkDeclaration::create(LINK p, Dsymbols *decl)
519 {
520     return new LinkDeclaration(p, decl);
521 }
522 
syntaxCopy(Dsymbol * s)523 Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s)
524 {
525     assert(!s);
526     return new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl));
527 }
528 
newScope(Scope * sc)529 Scope *LinkDeclaration::newScope(Scope *sc)
530 {
531     return createNewScope(sc, sc->stc, this->linkage, sc->cppmangle,
532         sc->protection, sc->explicitProtection, sc->aligndecl,
533         sc->inlining);
534 }
535 
toChars()536 const char *LinkDeclaration::toChars()
537 {
538     return "extern ()";
539 }
540 
541 /********************************* CPPMangleDeclaration ****************************/
542 
CPPMangleDeclaration(CPPMANGLE p,Dsymbols * decl)543 CPPMangleDeclaration::CPPMangleDeclaration(CPPMANGLE p, Dsymbols *decl)
544         : AttribDeclaration(decl)
545 {
546     //printf("CPPMangleDeclaration(cppmangle = %d, decl = %p)\n", p, decl);
547     cppmangle = p;
548 }
549 
syntaxCopy(Dsymbol * s)550 Dsymbol *CPPMangleDeclaration::syntaxCopy(Dsymbol *s)
551 {
552     assert(!s);
553     return new CPPMangleDeclaration(cppmangle, Dsymbol::arraySyntaxCopy(decl));
554 }
555 
newScope(Scope * sc)556 Scope *CPPMangleDeclaration::newScope(Scope *sc)
557 {
558     return createNewScope(sc, sc->stc, LINKcpp, this->cppmangle,
559         sc->protection, sc->explicitProtection, sc->aligndecl,
560         sc->inlining);
561 }
562 
toChars()563 const char *CPPMangleDeclaration::toChars()
564 {
565     return "extern ()";
566 }
567 
568 /********************************* ProtDeclaration ****************************/
569 
570 /**
571  * Params:
572  *  loc = source location of attribute token
573  *  p = protection attribute data
574  *  decl = declarations which are affected by this protection attribute
575  */
ProtDeclaration(Loc loc,Prot p,Dsymbols * decl)576 ProtDeclaration::ProtDeclaration(Loc loc, Prot p, Dsymbols *decl)
577         : AttribDeclaration(decl)
578 {
579     this->loc = loc;
580     this->protection = p;
581     this->pkg_identifiers = NULL;
582     //printf("decl = %p\n", decl);
583 }
584 
585 /**
586  * Params:
587  *  loc = source location of attribute token
588  *  pkg_identifiers = list of identifiers for a qualified package name
589  *  decl = declarations which are affected by this protection attribute
590  */
ProtDeclaration(Loc loc,Identifiers * pkg_identifiers,Dsymbols * decl)591 ProtDeclaration::ProtDeclaration(Loc loc, Identifiers* pkg_identifiers, Dsymbols *decl)
592         : AttribDeclaration(decl)
593 {
594     this->loc = loc;
595     this->protection.kind = PROTpackage;
596     this->protection.pkg  = NULL;
597     this->pkg_identifiers = pkg_identifiers;
598 }
599 
syntaxCopy(Dsymbol * s)600 Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s)
601 {
602     assert(!s);
603     if (protection.kind == PROTpackage)
604         return new ProtDeclaration(this->loc, pkg_identifiers, Dsymbol::arraySyntaxCopy(decl));
605     else
606         return new ProtDeclaration(this->loc, protection, Dsymbol::arraySyntaxCopy(decl));
607 }
608 
newScope(Scope * sc)609 Scope *ProtDeclaration::newScope(Scope *sc)
610 {
611     if (pkg_identifiers)
612         semantic(sc);
613     return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
614         this->protection, 1, sc->aligndecl,
615         sc->inlining);
616 }
617 
addMember(Scope * sc,ScopeDsymbol * sds)618 void ProtDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
619 {
620     if (pkg_identifiers)
621     {
622         Dsymbol* tmp;
623         Package::resolve(pkg_identifiers, &tmp, NULL);
624         protection.pkg = tmp ? tmp->isPackage() : NULL;
625         pkg_identifiers = NULL;
626     }
627 
628     if (protection.kind == PROTpackage && protection.pkg && sc->_module)
629     {
630         Module *m = sc->_module;
631         Package* pkg = m->parent ? m->parent->isPackage() : NULL;
632         if (!pkg || !protection.pkg->isAncestorPackageOf(pkg))
633             error("does not bind to one of ancestor packages of module '%s'",
634                m->toPrettyChars(true));
635     }
636 
637     return AttribDeclaration::addMember(sc, sds);
638 }
639 
kind()640 const char *ProtDeclaration::kind() const
641 {
642     return "protection attribute";
643 }
644 
toPrettyChars(bool)645 const char *ProtDeclaration::toPrettyChars(bool)
646 {
647     assert(protection.kind > PROTundefined);
648 
649     OutBuffer buf;
650     buf.writeByte('\'');
651     protectionToBuffer(&buf, protection);
652     buf.writeByte('\'');
653     return buf.extractString();
654 }
655 
656 /********************************* AlignDeclaration ****************************/
657 
AlignDeclaration(Loc loc,Expression * ealign,Dsymbols * decl)658 AlignDeclaration::AlignDeclaration(Loc loc, Expression *ealign, Dsymbols *decl)
659         : AttribDeclaration(decl)
660 {
661     this->loc = loc;
662     this->ealign = ealign;
663     this->salign = 0;
664 }
665 
syntaxCopy(Dsymbol * s)666 Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s)
667 {
668     assert(!s);
669     return new AlignDeclaration(loc,
670         ealign->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl));
671 }
672 
newScope(Scope * sc)673 Scope *AlignDeclaration::newScope(Scope *sc)
674 {
675     return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
676         sc->protection, sc->explicitProtection, this,
677         sc->inlining);
678 }
679 
semantic2(Scope * sc)680 void AlignDeclaration::semantic2(Scope *sc)
681 {
682     getAlignment(sc);
683     AttribDeclaration::semantic2(sc);
684 }
685 
getAlignment(Scope * sc)686 structalign_t AlignDeclaration::getAlignment(Scope *sc)
687 {
688     if (salign != 0)
689         return salign;
690 
691     if (!ealign)
692         return salign = STRUCTALIGN_DEFAULT;
693 
694     sc = sc->startCTFE();
695     ealign = ::semantic(ealign, sc);
696     ealign = resolveProperties(sc, ealign);
697     sc = sc->endCTFE();
698     ealign = ealign->ctfeInterpret();
699 
700     if (ealign->op == TOKerror)
701         return salign = STRUCTALIGN_DEFAULT;
702 
703     Type *tb = ealign->type->toBasetype();
704     sinteger_t n = ealign->toInteger();
705 
706     if (n < 1 || n & (n - 1) || STRUCTALIGN_DEFAULT < n || !tb->isintegral())
707     {
708         ::error(loc, "alignment must be an integer positive power of 2, not %s", ealign->toChars());
709         return salign = STRUCTALIGN_DEFAULT;
710     }
711 
712     return salign = (structalign_t)n;
713 }
714 
715 /********************************* AnonDeclaration ****************************/
716 
AnonDeclaration(Loc loc,bool isunion,Dsymbols * decl)717 AnonDeclaration::AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl)
718         : AttribDeclaration(decl)
719 {
720     this->loc = loc;
721     this->isunion = isunion;
722     this->sem = 0;
723     this->anonoffset = 0;
724     this->anonstructsize = 0;
725     this->anonalignsize = 0;
726 }
727 
syntaxCopy(Dsymbol * s)728 Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s)
729 {
730     assert(!s);
731     return new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl));
732 }
733 
setScope(Scope * sc)734 void AnonDeclaration::setScope(Scope *sc)
735 {
736     //printf("AnonDeclaration::setScope() %p\n", this);
737     if (decl)
738         Dsymbol::setScope(sc);
739     AttribDeclaration::setScope(sc);
740 }
741 
semantic(Scope * sc)742 void AnonDeclaration::semantic(Scope *sc)
743 {
744     //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
745 
746     assert(sc->parent);
747 
748     Dsymbol *p = sc->parent->pastMixin();
749     AggregateDeclaration *ad = p->isAggregateDeclaration();
750     if (!ad)
751     {
752         ::error(loc, "%s can only be a part of an aggregate, not %s %s",
753             kind(), p->kind(), p->toChars());
754         return;
755     }
756 
757     if (decl)
758     {
759         sc = sc->push();
760         sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared);
761         sc->inunion = isunion;
762         sc->flags = 0;
763 
764         for (size_t i = 0; i < decl->dim; i++)
765         {
766             Dsymbol *s = (*decl)[i];
767             s->semantic(sc);
768         }
769         sc = sc->pop();
770     }
771 }
772 
setFieldOffset(AggregateDeclaration * ad,unsigned * poffset,bool isunion)773 void AnonDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
774 {
775     //printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this);
776 
777     if (decl)
778     {
779         /* This works by treating an AnonDeclaration as an aggregate 'member',
780          * so in order to place that member we need to compute the member's
781          * size and alignment.
782          */
783 
784         size_t fieldstart = ad->fields.dim;
785 
786         /* Hackishly hijack ad's structsize and alignsize fields
787          * for use in our fake anon aggregate member.
788          */
789         unsigned savestructsize = ad->structsize;
790         unsigned savealignsize  = ad->alignsize;
791         ad->structsize = 0;
792         ad->alignsize = 0;
793 
794         unsigned offset = 0;
795         for (size_t i = 0; i < decl->dim; i++)
796         {
797             Dsymbol *s = (*decl)[i];
798             s->setFieldOffset(ad, &offset, this->isunion);
799             if (this->isunion)
800                 offset = 0;
801         }
802 
803         /* Bugzilla 13613: If the fields in this->members had been already
804          * added in ad->fields, just update *poffset for the subsequent
805          * field offset calculation.
806          */
807         if (fieldstart == ad->fields.dim)
808         {
809             ad->structsize = savestructsize;
810             ad->alignsize  = savealignsize;
811             *poffset = ad->structsize;
812             return;
813         }
814 
815         anonstructsize = ad->structsize;
816         anonalignsize  = ad->alignsize;
817         ad->structsize = savestructsize;
818         ad->alignsize  = savealignsize;
819 
820         // 0 sized structs are set to 1 byte
821         // TODO: is this corect hebavior?
822         if (anonstructsize == 0)
823         {
824             anonstructsize = 1;
825             anonalignsize = 1;
826         }
827 
828         assert(_scope);
829         structalign_t alignment = _scope->alignment();
830 
831         /* Given the anon 'member's size and alignment,
832          * go ahead and place it.
833          */
834         anonoffset = AggregateDeclaration::placeField(
835                 poffset,
836                 anonstructsize, anonalignsize, alignment,
837                 &ad->structsize, &ad->alignsize,
838                 isunion);
839 
840         // Add to the anon fields the base offset of this anonymous aggregate
841         //printf("anon fields, anonoffset = %d\n", anonoffset);
842         for (size_t i = fieldstart; i < ad->fields.dim; i++)
843         {
844             VarDeclaration *v = ad->fields[i];
845             //printf("\t[%d] %s %d\n", i, v->toChars(), v->offset);
846             v->offset += anonoffset;
847         }
848     }
849 }
850 
kind()851 const char *AnonDeclaration::kind() const
852 {
853     return (isunion ? "anonymous union" : "anonymous struct");
854 }
855 
856 /********************************* PragmaDeclaration ****************************/
857 
PragmaDeclaration(Loc loc,Identifier * ident,Expressions * args,Dsymbols * decl)858 PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl)
859         : AttribDeclaration(decl)
860 {
861     this->loc = loc;
862     this->ident = ident;
863     this->args = args;
864 }
865 
syntaxCopy(Dsymbol * s)866 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s)
867 {
868     //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars());
869     assert(!s);
870     return new PragmaDeclaration(loc, ident,
871         Expression::arraySyntaxCopy(args),
872         Dsymbol::arraySyntaxCopy(decl));
873 }
874 
newScope(Scope * sc)875 Scope *PragmaDeclaration::newScope(Scope *sc)
876 {
877     if (ident == Id::Pinline)
878     {
879         PINLINE inlining = PINLINEdefault;
880         if (!args || args->dim == 0)
881             inlining = PINLINEdefault;
882         else if (args->dim != 1)
883         {
884             error("one boolean expression expected for pragma(inline), not %d", args->dim);
885             args->setDim(1);
886             (*args)[0] = new ErrorExp();
887         }
888         else
889         {
890             Expression *e = (*args)[0];
891 
892             if (e->op != TOKint64 || !e->type->equals(Type::tbool))
893             {
894                 if (e->op != TOKerror)
895                 {
896                     error("pragma(inline, true or false) expected, not %s", e->toChars());
897                     (*args)[0] = new ErrorExp();
898                 }
899             }
900             else if (e->isBool(true))
901                 inlining = PINLINEalways;
902             else if (e->isBool(false))
903                 inlining = PINLINEnever;
904         }
905 
906         return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
907             sc->protection, sc->explicitProtection, sc->aligndecl,
908             inlining);
909     }
910     return sc;
911 }
912 
setMangleOverride(Dsymbol * s,char * sym)913 static unsigned setMangleOverride(Dsymbol *s, char *sym)
914 {
915     AttribDeclaration *ad = s->isAttribDeclaration();
916 
917     if (ad)
918     {
919         Dsymbols *decls = ad->include(NULL, NULL);
920         unsigned nestedCount = 0;
921 
922         if (decls && decls->dim)
923             for (size_t i = 0; i < decls->dim; ++i)
924                 nestedCount += setMangleOverride((*decls)[i], sym);
925 
926         return nestedCount;
927     }
928     else if (s->isFuncDeclaration() || s->isVarDeclaration())
929     {
930         s->isDeclaration()->mangleOverride = sym;
931         return 1;
932     }
933     else
934         return 0;
935 }
936 
semantic(Scope * sc)937 void PragmaDeclaration::semantic(Scope *sc)
938 {
939     // Should be merged with PragmaStatement
940 
941     //printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
942     if (ident == Id::msg)
943     {
944         if (args)
945         {
946             for (size_t i = 0; i < args->dim; i++)
947             {
948                 Expression *e = (*args)[i];
949 
950                 sc = sc->startCTFE();
951                 e = ::semantic(e, sc);
952                 e = resolveProperties(sc, e);
953                 sc = sc->endCTFE();
954 
955                 // pragma(msg) is allowed to contain types as well as expressions
956                 e = ctfeInterpretForPragmaMsg(e);
957                 if (e->op == TOKerror)
958                 {
959                     errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
960                     return;
961                 }
962                 StringExp *se = e->toStringExp();
963                 if (se)
964                 {
965                     se = se->toUTF8(sc);
966                     fprintf(stderr, "%.*s", (int)se->len, (char *)se->string);
967                 }
968                 else
969                     fprintf(stderr, "%s", e->toChars());
970             }
971             fprintf(stderr, "\n");
972         }
973         goto Lnodecl;
974     }
975     else if (ident == Id::lib)
976     {
977         if (!args || args->dim != 1)
978             error("string expected for library name");
979         else
980         {
981             StringExp *se = semanticString(sc, (*args)[0], "library name");
982             if (!se)
983                 goto Lnodecl;
984             (*args)[0] = se;
985 
986             char *name = (char *)mem.xmalloc(se->len + 1);
987             memcpy(name, se->string, se->len);
988             name[se->len] = 0;
989             if (global.params.verbose)
990                 message("library   %s", name);
991             if (global.params.moduleDeps && !global.params.moduleDepsFile)
992             {
993                 OutBuffer *ob = global.params.moduleDeps;
994                 Module *imod = sc->instantiatingModule();
995                 ob->writestring("depsLib ");
996                 ob->writestring(imod->toPrettyChars());
997                 ob->writestring(" (");
998                 escapePath(ob, imod->srcfile->toChars());
999                 ob->writestring(") : ");
1000                 ob->writestring((char *) name);
1001                 ob->writenl();
1002             }
1003             mem.xfree(name);
1004         }
1005         goto Lnodecl;
1006     }
1007     else if (ident == Id::startaddress)
1008     {
1009         if (!args || args->dim != 1)
1010             error("function name expected for start address");
1011         else
1012         {
1013             /* Bugzilla 11980:
1014              * resolveProperties and ctfeInterpret call are not necessary.
1015              */
1016             Expression *e = (*args)[0];
1017 
1018             sc = sc->startCTFE();
1019             e = ::semantic(e, sc);
1020             sc = sc->endCTFE();
1021 
1022             (*args)[0] = e;
1023             Dsymbol *sa = getDsymbol(e);
1024             if (!sa || !sa->isFuncDeclaration())
1025                 error("function name expected for start address, not '%s'", e->toChars());
1026         }
1027         goto Lnodecl;
1028     }
1029     else if (ident == Id::Pinline)
1030     {
1031         goto Ldecl;
1032     }
1033     else if (ident == Id::mangle)
1034     {
1035         if (!args)
1036             args = new Expressions();
1037         if (args->dim != 1)
1038         {
1039             error("string expected for mangled name");
1040             args->setDim(1);
1041             (*args)[0] = new ErrorExp();    // error recovery
1042             goto Ldecl;
1043         }
1044 
1045         StringExp *se = semanticString(sc, (*args)[0], "mangled name");
1046         if (!se)
1047             goto Ldecl;
1048         (*args)[0] = se; // Will be used for later
1049 
1050         if (!se->len)
1051         {
1052             error("zero-length string not allowed for mangled name");
1053             goto Ldecl;
1054         }
1055         if (se->sz != 1)
1056         {
1057             error("mangled name characters can only be of type char");
1058             goto Ldecl;
1059         }
1060 
1061         /* Note: D language specification should not have any assumption about backend
1062          * implementation. Ideally pragma(mangle) can accept a string of any content.
1063          *
1064          * Therefore, this validation is compiler implementation specific.
1065          */
1066         for (size_t i = 0; i < se->len; )
1067         {
1068             utf8_t *p = (utf8_t *)se->string;
1069             dchar_t c = p[i];
1070             if (c < 0x80)
1071             {
1072                 if ((c >= 'A' && c <= 'Z') ||
1073                     (c >= 'a' && c <= 'z') ||
1074                     (c >= '0' && c <= '9') ||
1075                     (c != 0 && strchr("$%().:?@[]_", c)))
1076                 {
1077                     ++i;
1078                     continue;
1079                 }
1080                 else
1081                 {
1082                     error("char 0x%02x not allowed in mangled name", c);
1083                     break;
1084                 }
1085             }
1086 
1087             if (const char* msg = utf_decodeChar((utf8_t *)se->string, se->len, &i, &c))
1088             {
1089                 error("%s", msg);
1090                 break;
1091             }
1092 
1093             if (!isUniAlpha(c))
1094             {
1095                 error("char 0x%04x not allowed in mangled name", c);
1096                 break;
1097             }
1098         }
1099     }
1100     else if (global.params.ignoreUnsupportedPragmas)
1101     {
1102         if (global.params.verbose)
1103         {
1104             /* Print unrecognized pragmas
1105              */
1106             OutBuffer buf;
1107             buf.writestring(ident->toChars());
1108             if (args)
1109             {
1110                 for (size_t i = 0; i < args->dim; i++)
1111                 {
1112                     Expression *e = (*args)[i];
1113 
1114                     sc = sc->startCTFE();
1115                     e = ::semantic(e, sc);
1116                     e = resolveProperties(sc, e);
1117                     sc = sc->endCTFE();
1118 
1119                     e = e->ctfeInterpret();
1120                     if (i == 0)
1121                         buf.writestring(" (");
1122                     else
1123                         buf.writeByte(',');
1124                     buf.writestring(e->toChars());
1125                 }
1126                 if (args->dim)
1127                     buf.writeByte(')');
1128             }
1129             message("pragma    %s", buf.peekString());
1130         }
1131         goto Lnodecl;
1132     }
1133     else
1134         error("unrecognized pragma(%s)", ident->toChars());
1135 
1136 Ldecl:
1137     if (decl)
1138     {
1139         Scope *sc2 = newScope(sc);
1140 
1141         for (size_t i = 0; i < decl->dim; i++)
1142         {
1143             Dsymbol *s = (*decl)[i];
1144 
1145             s->semantic(sc2);
1146 
1147             if (ident == Id::mangle)
1148             {
1149                 assert(args && args->dim == 1);
1150                 if (StringExp *se = (*args)[0]->toStringExp())
1151                 {
1152                     char *name = (char *)mem.xmalloc(se->len + 1);
1153                     memcpy(name, se->string, se->len);
1154                     name[se->len] = 0;
1155 
1156                     unsigned cnt = setMangleOverride(s, name);
1157                     if (cnt > 1)
1158                         error("can only apply to a single declaration");
1159                 }
1160             }
1161         }
1162 
1163         if (sc2 != sc)
1164             sc2->pop();
1165     }
1166     return;
1167 
1168 Lnodecl:
1169     if (decl)
1170     {
1171         error("pragma is missing closing ';'");
1172         goto Ldecl; // do them anyway, to avoid segfaults.
1173     }
1174 }
1175 
kind()1176 const char *PragmaDeclaration::kind() const
1177 {
1178     return "pragma";
1179 }
1180 
1181 /********************************* ConditionalDeclaration ****************************/
1182 
ConditionalDeclaration(Condition * condition,Dsymbols * decl,Dsymbols * elsedecl)1183 ConditionalDeclaration::ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl)
1184         : AttribDeclaration(decl)
1185 {
1186     //printf("ConditionalDeclaration::ConditionalDeclaration()\n");
1187     this->condition = condition;
1188     this->elsedecl = elsedecl;
1189 }
1190 
syntaxCopy(Dsymbol * s)1191 Dsymbol *ConditionalDeclaration::syntaxCopy(Dsymbol *s)
1192 {
1193     assert(!s);
1194     return new ConditionalDeclaration(condition->syntaxCopy(),
1195         Dsymbol::arraySyntaxCopy(decl),
1196         Dsymbol::arraySyntaxCopy(elsedecl));
1197 }
1198 
oneMember(Dsymbol ** ps,Identifier * ident)1199 bool ConditionalDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
1200 {
1201     //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
1202     if (condition->inc)
1203     {
1204         Dsymbols *d = condition->include(NULL, NULL) ? decl : elsedecl;
1205         return Dsymbol::oneMembers(d, ps, ident);
1206     }
1207     else
1208     {
1209         bool res = (Dsymbol::oneMembers(    decl, ps, ident) && *ps == NULL &&
1210                     Dsymbol::oneMembers(elsedecl, ps, ident) && *ps == NULL);
1211         *ps = NULL;
1212         return res;
1213     }
1214 }
1215 
1216 // Decide if 'then' or 'else' code should be included
1217 
include(Scope * sc,ScopeDsymbol * sds)1218 Dsymbols *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sds)
1219 {
1220     //printf("ConditionalDeclaration::include(sc = %p) _scope = %p\n", sc, _scope);
1221     assert(condition);
1222     return condition->include(_scope ? _scope : sc, sds) ? decl : elsedecl;
1223 }
1224 
setScope(Scope * sc)1225 void ConditionalDeclaration::setScope(Scope *sc)
1226 {
1227     Dsymbols *d = include(sc, NULL);
1228 
1229     //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
1230     if (d)
1231     {
1232        for (size_t i = 0; i < d->dim; i++)
1233        {
1234            Dsymbol *s = (*d)[i];
1235            s->setScope(sc);
1236        }
1237     }
1238 }
1239 
addComment(const utf8_t * comment)1240 void ConditionalDeclaration::addComment(const utf8_t *comment)
1241 {
1242     /* Because addComment is called by the parser, if we called
1243      * include() it would define a version before it was used.
1244      * But it's no problem to drill down to both decl and elsedecl,
1245      * so that's the workaround.
1246      */
1247 
1248     if (comment)
1249     {
1250         Dsymbols *d = decl;
1251 
1252         for (int j = 0; j < 2; j++)
1253         {
1254             if (d)
1255             {
1256                 for (size_t i = 0; i < d->dim; i++)
1257                 {
1258                     Dsymbol *s = (*d)[i];
1259                     //printf("ConditionalDeclaration::addComment %s\n", s->toChars());
1260                     s->addComment(comment);
1261                 }
1262             }
1263             d = elsedecl;
1264         }
1265     }
1266 }
1267 
1268 /***************************** StaticIfDeclaration ****************************/
1269 
StaticIfDeclaration(Condition * condition,Dsymbols * decl,Dsymbols * elsedecl)1270 StaticIfDeclaration::StaticIfDeclaration(Condition *condition,
1271         Dsymbols *decl, Dsymbols *elsedecl)
1272         : ConditionalDeclaration(condition, decl, elsedecl)
1273 {
1274     //printf("StaticIfDeclaration::StaticIfDeclaration()\n");
1275     scopesym = NULL;
1276     addisdone = false;
1277 }
1278 
syntaxCopy(Dsymbol * s)1279 Dsymbol *StaticIfDeclaration::syntaxCopy(Dsymbol *s)
1280 {
1281     assert(!s);
1282     return new StaticIfDeclaration(condition->syntaxCopy(),
1283         Dsymbol::arraySyntaxCopy(decl),
1284         Dsymbol::arraySyntaxCopy(elsedecl));
1285 }
1286 
1287 /****************************************
1288  * Different from other AttribDeclaration subclasses, include() call requires
1289  * the completion of addMember and setScope phases.
1290  */
include(Scope * sc,ScopeDsymbol *)1291 Dsymbols *StaticIfDeclaration::include(Scope *sc, ScopeDsymbol *)
1292 {
1293     //printf("StaticIfDeclaration::include(sc = %p) _scope = %p\n", sc, _scope);
1294 
1295     if (condition->inc == 0)
1296     {
1297         assert(scopesym);   // addMember is already done
1298         assert(_scope);      // setScope is already done
1299 
1300         Dsymbols *d = ConditionalDeclaration::include(_scope, scopesym);
1301 
1302         if (d && !addisdone)
1303         {
1304             // Add members lazily.
1305             for (size_t i = 0; i < d->dim; i++)
1306             {
1307                 Dsymbol *s = (*d)[i];
1308                 s->addMember(_scope, scopesym);
1309             }
1310 
1311             // Set the member scopes lazily.
1312             for (size_t i = 0; i < d->dim; i++)
1313             {
1314                 Dsymbol *s = (*d)[i];
1315                 s->setScope(_scope);
1316             }
1317 
1318             addisdone = true;
1319         }
1320         return d;
1321     }
1322     else
1323     {
1324         return ConditionalDeclaration::include(sc, scopesym);
1325     }
1326 }
1327 
addMember(Scope *,ScopeDsymbol * sds)1328 void StaticIfDeclaration::addMember(Scope *, ScopeDsymbol *sds)
1329 {
1330     //printf("StaticIfDeclaration::addMember() '%s'\n", toChars());
1331     /* This is deferred until the condition evaluated later (by the include() call),
1332      * so that expressions in the condition can refer to declarations
1333      * in the same scope, such as:
1334      *
1335      * template Foo(int i)
1336      * {
1337      *     const int j = i + 1;
1338      *     static if (j == 3)
1339      *         const int k;
1340      * }
1341      */
1342     this->scopesym = sds;
1343 }
1344 
importAll(Scope *)1345 void StaticIfDeclaration::importAll(Scope *)
1346 {
1347     // do not evaluate condition before semantic pass
1348 }
1349 
setScope(Scope * sc)1350 void StaticIfDeclaration::setScope(Scope *sc)
1351 {
1352     // do not evaluate condition before semantic pass
1353 
1354     // But do set the scope, in case we need it for forward referencing
1355     Dsymbol::setScope(sc);
1356 }
1357 
semantic(Scope * sc)1358 void StaticIfDeclaration::semantic(Scope *sc)
1359 {
1360     AttribDeclaration::semantic(sc);
1361 }
1362 
kind()1363 const char *StaticIfDeclaration::kind() const
1364 {
1365     return "static if";
1366 }
1367 
1368 /***************************** CompileDeclaration *****************************/
1369 
1370 // These are mixin declarations, like mixin("int x");
1371 
CompileDeclaration(Loc loc,Expression * exp)1372 CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp)
1373     : AttribDeclaration(NULL)
1374 {
1375     //printf("CompileDeclaration(loc = %d)\n", loc.linnum);
1376     this->loc = loc;
1377     this->exp = exp;
1378     this->scopesym = NULL;
1379     this->compiled = false;
1380 }
1381 
syntaxCopy(Dsymbol *)1382 Dsymbol *CompileDeclaration::syntaxCopy(Dsymbol *)
1383 {
1384     //printf("CompileDeclaration::syntaxCopy('%s')\n", toChars());
1385     return new CompileDeclaration(loc, exp->syntaxCopy());
1386 }
1387 
addMember(Scope *,ScopeDsymbol * sds)1388 void CompileDeclaration::addMember(Scope *, ScopeDsymbol *sds)
1389 {
1390     //printf("CompileDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\n", sc, sds, memnum);
1391     this->scopesym = sds;
1392 }
1393 
setScope(Scope * sc)1394 void CompileDeclaration::setScope(Scope *sc)
1395 {
1396     Dsymbol::setScope(sc);
1397 }
1398 
compileIt(Scope * sc)1399 void CompileDeclaration::compileIt(Scope *sc)
1400 {
1401     //printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars());
1402     StringExp *se = semanticString(sc, exp, "argument to mixin");
1403     if (!se)
1404         return;
1405     se = se->toUTF8(sc);
1406 
1407     unsigned errors = global.errors;
1408     Parser p(loc, sc->_module, (utf8_t *)se->string, se->len, 0);
1409     p.nextToken();
1410 
1411     decl = p.parseDeclDefs(0);
1412     if (p.token.value != TOKeof)
1413         exp->error("incomplete mixin declaration (%s)", se->toChars());
1414     if (p.errors)
1415     {
1416         assert(global.errors != errors);
1417         decl = NULL;
1418     }
1419 }
1420 
semantic(Scope * sc)1421 void CompileDeclaration::semantic(Scope *sc)
1422 {
1423     //printf("CompileDeclaration::semantic()\n");
1424 
1425     if (!compiled)
1426     {
1427         compileIt(sc);
1428         AttribDeclaration::addMember(sc, scopesym);
1429         compiled = true;
1430 
1431         if (_scope && decl)
1432         {
1433             for (size_t i = 0; i < decl->dim; i++)
1434             {
1435                 Dsymbol *s = (*decl)[i];
1436                 s->setScope(_scope);
1437             }
1438         }
1439     }
1440     AttribDeclaration::semantic(sc);
1441 }
1442 
kind()1443 const char *CompileDeclaration::kind() const
1444 {
1445     return "mixin";
1446 }
1447 
1448 /***************************** UserAttributeDeclaration *****************************/
1449 
UserAttributeDeclaration(Expressions * atts,Dsymbols * decl)1450 UserAttributeDeclaration::UserAttributeDeclaration(Expressions *atts, Dsymbols *decl)
1451         : AttribDeclaration(decl)
1452 {
1453     //printf("UserAttributeDeclaration()\n");
1454     this->atts = atts;
1455 }
1456 
syntaxCopy(Dsymbol * s)1457 Dsymbol *UserAttributeDeclaration::syntaxCopy(Dsymbol *s)
1458 {
1459     //printf("UserAttributeDeclaration::syntaxCopy('%s')\n", toChars());
1460     assert(!s);
1461     return new UserAttributeDeclaration(
1462         Expression::arraySyntaxCopy(this->atts),
1463         Dsymbol::arraySyntaxCopy(decl));
1464 }
1465 
newScope(Scope * sc)1466 Scope *UserAttributeDeclaration::newScope(Scope *sc)
1467 {
1468     Scope *sc2 = sc;
1469     if (atts && atts->dim)
1470     {
1471         // create new one for changes
1472         sc2 = sc->copy();
1473         sc2->userAttribDecl = this;
1474     }
1475     return sc2;
1476 }
1477 
setScope(Scope * sc)1478 void UserAttributeDeclaration::setScope(Scope *sc)
1479 {
1480     //printf("UserAttributeDeclaration::setScope() %p\n", this);
1481     if (decl)
1482         Dsymbol::setScope(sc);  // for forward reference of UDAs
1483 
1484     return AttribDeclaration::setScope(sc);
1485 }
1486 
semantic(Scope * sc)1487 void UserAttributeDeclaration::semantic(Scope *sc)
1488 {
1489     //printf("UserAttributeDeclaration::semantic() %p\n", this);
1490     if (decl && !_scope)
1491         Dsymbol::setScope(sc);  // for function local symbols
1492 
1493     return AttribDeclaration::semantic(sc);
1494 }
1495 
udaExpressionEval(Scope * sc,Expressions * exps)1496 static void udaExpressionEval(Scope *sc, Expressions *exps)
1497 {
1498     for (size_t i = 0; i < exps->dim; i++)
1499     {
1500         Expression *e = (*exps)[i];
1501         if (e)
1502         {
1503             e = ::semantic(e, sc);
1504             if (definitelyValueParameter(e))
1505                 e = e->ctfeInterpret();
1506             if (e->op == TOKtuple)
1507             {
1508                 TupleExp *te = (TupleExp *)e;
1509                 udaExpressionEval(sc, te->exps);
1510             }
1511             (*exps)[i] = e;
1512         }
1513     }
1514 }
1515 
semantic2(Scope * sc)1516 void UserAttributeDeclaration::semantic2(Scope *sc)
1517 {
1518     if (decl && atts && atts->dim && _scope)
1519     {
1520         _scope = NULL;
1521         udaExpressionEval(sc, atts);
1522     }
1523 
1524     AttribDeclaration::semantic2(sc);
1525 }
1526 
concat(Expressions * udas1,Expressions * udas2)1527 Expressions *UserAttributeDeclaration::concat(Expressions *udas1, Expressions *udas2)
1528 {
1529     Expressions *udas;
1530     if (!udas1 || udas1->dim == 0)
1531         udas = udas2;
1532     else if (!udas2 || udas2->dim == 0)
1533         udas = udas1;
1534     else
1535     {
1536         /* Create a new tuple that combines them
1537          * (do not append to left operand, as this is a copy-on-write operation)
1538          */
1539         udas = new Expressions();
1540         udas->push(new TupleExp(Loc(), udas1));
1541         udas->push(new TupleExp(Loc(), udas2));
1542     }
1543     return udas;
1544 }
1545 
getAttributes()1546 Expressions *UserAttributeDeclaration::getAttributes()
1547 {
1548     if (Scope *sc = _scope)
1549     {
1550         _scope = NULL;
1551         arrayExpressionSemantic(atts, sc);
1552     }
1553 
1554     Expressions *exps = new Expressions();
1555     if (userAttribDecl)
1556         exps->push(new TupleExp(Loc(), userAttribDecl->getAttributes()));
1557     if (atts && atts->dim)
1558         exps->push(new TupleExp(Loc(), atts));
1559 
1560     return exps;
1561 }
1562 
kind()1563 const char *UserAttributeDeclaration::kind() const
1564 {
1565     return "UserAttribute";
1566 }
1567