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