]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/attrib.c
c4270ea63e66686611f8a580aaf77a9e762a5b89
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/attrib.c
14 #include <string.h> // memcpy()
16 #include "root/rmem.h"
20 #include "declaration.h"
25 #include "expression.h"
27 #include "aggregate.h"
35 bool definitelyValueParameter(Expression
*e
);
36 Expression
*semantic(Expression
*e
, Scope
*sc
);
38 /********************************* AttribDeclaration ****************************/
40 AttribDeclaration::AttribDeclaration(Dsymbols
*decl
)
46 Dsymbols
*AttribDeclaration::include(Scope
*, ScopeDsymbol
*)
51 int AttribDeclaration::apply(Dsymbol_apply_ft_t fp
, void *param
)
53 Dsymbols
*d
= include(_scope
, NULL
);
57 for (size_t i
= 0; i
< d
->dim
; i
++)
62 if (s
->apply(fp
, param
))
70 /****************************************
71 * Create a new scope if one or more given attributes
72 * are different from the sc's.
73 * If the returned scope != sc, the caller should pop
74 * the scope after it used.
76 Scope
*AttribDeclaration::createNewScope(Scope
*sc
,
77 StorageClass stc
, LINK linkage
, CPPMANGLE cppmangle
, Prot protection
,
78 int explicitProtection
, AlignDeclaration
*aligndecl
, PINLINE inlining
)
82 linkage
!= sc
->linkage
||
83 cppmangle
!= sc
->cppmangle
||
84 !protection
.isSubsetOf(sc
->protection
) ||
85 explicitProtection
!= sc
->explicitProtection
||
86 aligndecl
!= sc
->aligndecl
||
87 inlining
!= sc
->inlining
)
89 // create new one for changes
92 sc2
->linkage
= linkage
;
93 sc2
->cppmangle
= cppmangle
;
94 sc2
->protection
= protection
;
95 sc2
->explicitProtection
= explicitProtection
;
96 sc2
->aligndecl
= aligndecl
;
97 sc2
->inlining
= inlining
;
102 /****************************************
103 * A hook point to supply scope for members.
104 * addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this.
106 Scope
*AttribDeclaration::newScope(Scope
*sc
)
111 void AttribDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sds
)
113 Dsymbols
*d
= include(sc
, sds
);
117 Scope
*sc2
= newScope(sc
);
119 for (size_t i
= 0; i
< d
->dim
; i
++)
121 Dsymbol
*s
= (*d
)[i
];
122 //printf("\taddMember %s to %s\n", s->toChars(), sds->toChars());
123 s
->addMember(sc2
, sds
);
131 void AttribDeclaration::setScope(Scope
*sc
)
133 Dsymbols
*d
= include(sc
, NULL
);
135 //printf("\tAttribDeclaration::setScope '%s', d = %p\n",toChars(), d);
138 Scope
*sc2
= newScope(sc
);
140 for (size_t i
= 0; i
< d
->dim
; i
++)
142 Dsymbol
*s
= (*d
)[i
];
151 void AttribDeclaration::importAll(Scope
*sc
)
153 Dsymbols
*d
= include(sc
, NULL
);
155 //printf("\tAttribDeclaration::importAll '%s', d = %p\n", toChars(), d);
158 Scope
*sc2
= newScope(sc
);
160 for (size_t i
= 0; i
< d
->dim
; i
++)
162 Dsymbol
*s
= (*d
)[i
];
171 void AttribDeclaration::semantic(Scope
*sc
)
173 if (semanticRun
!= PASSinit
)
175 semanticRun
= PASSsemantic
;
176 Dsymbols
*d
= include(sc
, NULL
);
178 //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
181 Scope
*sc2
= newScope(sc
);
183 for (size_t i
= 0; i
< d
->dim
; i
++)
185 Dsymbol
*s
= (*d
)[i
];
192 semanticRun
= PASSsemanticdone
;
195 void AttribDeclaration::semantic2(Scope
*sc
)
197 Dsymbols
*d
= include(sc
, NULL
);
201 Scope
*sc2
= newScope(sc
);
203 for (size_t i
= 0; i
< d
->dim
; i
++)
205 Dsymbol
*s
= (*d
)[i
];
214 void AttribDeclaration::semantic3(Scope
*sc
)
216 Dsymbols
*d
= include(sc
, NULL
);
220 Scope
*sc2
= newScope(sc
);
222 for (size_t i
= 0; i
< d
->dim
; i
++)
224 Dsymbol
*s
= (*d
)[i
];
233 void AttribDeclaration::addComment(const utf8_t
*comment
)
235 //printf("AttribDeclaration::addComment %s\n", comment);
238 Dsymbols
*d
= include(NULL
, NULL
);
242 for (size_t i
= 0; i
< d
->dim
; i
++)
244 Dsymbol
*s
= (*d
)[i
];
245 //printf("AttribDeclaration::addComment %s\n", s->toChars());
246 s
->addComment(comment
);
252 void AttribDeclaration::setFieldOffset(AggregateDeclaration
*ad
, unsigned *poffset
, bool isunion
)
254 Dsymbols
*d
= include(NULL
, NULL
);
258 for (size_t i
= 0; i
< d
->dim
; i
++)
260 Dsymbol
*s
= (*d
)[i
];
261 s
->setFieldOffset(ad
, poffset
, isunion
);
266 bool AttribDeclaration::hasPointers()
268 Dsymbols
*d
= include(NULL
, NULL
);
272 for (size_t i
= 0; i
< d
->dim
; i
++)
274 Dsymbol
*s
= (*d
)[i
];
275 if (s
->hasPointers())
282 bool AttribDeclaration::hasStaticCtorOrDtor()
284 Dsymbols
*d
= include(NULL
, NULL
);
288 for (size_t i
= 0; i
< d
->dim
; i
++)
290 Dsymbol
*s
= (*d
)[i
];
291 if (s
->hasStaticCtorOrDtor())
298 const char *AttribDeclaration::kind() const
303 bool AttribDeclaration::oneMember(Dsymbol
**ps
, Identifier
*ident
)
305 Dsymbols
*d
= include(NULL
, NULL
);
307 return Dsymbol::oneMembers(d
, ps
, ident
);
310 void AttribDeclaration::checkCtorConstInit()
312 Dsymbols
*d
= include(NULL
, NULL
);
316 for (size_t i
= 0; i
< d
->dim
; i
++)
318 Dsymbol
*s
= (*d
)[i
];
319 s
->checkCtorConstInit();
324 /****************************************
327 void AttribDeclaration::addLocalClass(ClassDeclarations
*aclasses
)
329 Dsymbols
*d
= include(NULL
, NULL
);
333 for (size_t i
= 0; i
< d
->dim
; i
++)
335 Dsymbol
*s
= (*d
)[i
];
336 s
->addLocalClass(aclasses
);
341 /************************* StorageClassDeclaration ****************************/
343 StorageClassDeclaration::StorageClassDeclaration(StorageClass stc
, Dsymbols
*decl
)
344 : AttribDeclaration(decl
)
349 Dsymbol
*StorageClassDeclaration::syntaxCopy(Dsymbol
*s
)
352 return new StorageClassDeclaration(stc
, Dsymbol::arraySyntaxCopy(decl
));
355 bool StorageClassDeclaration::oneMember(Dsymbol
**ps
, Identifier
*ident
)
357 bool t
= Dsymbol::oneMembers(decl
, ps
, ident
);
360 /* This is to deal with the following case:
362 * template to(T) { const T to() { ... } }
364 * For eponymous function templates, the 'const' needs to get attached to 'to'
365 * before the semantic analysis of 'to', so that template overloading based on the
366 * 'this' pointer can be successful.
369 FuncDeclaration
*fd
= (*ps
)->isFuncDeclaration();
372 /* Use storage_class2 instead of storage_class otherwise when we do .di generation
373 * we'll wind up with 'const const' rather than 'const'.
375 /* Don't think we need to worry about mutually exclusive storage classes here
377 fd
->storage_class2
|= stc
;
383 void StorageClassDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sds
)
385 Dsymbols
*d
= include(sc
, sds
);
388 Scope
*sc2
= newScope(sc
);
389 for (size_t i
= 0; i
< d
->dim
; i
++)
391 Dsymbol
*s
= (*d
)[i
];
392 //printf("\taddMember %s to %s\n", s->toChars(), sds->toChars());
393 // STClocal needs to be attached before the member is added to the scope (because it influences the parent symbol)
394 if (Declaration
*decl
= s
->isDeclaration())
396 decl
->storage_class
|= stc
& STClocal
;
397 if (StorageClassDeclaration
*sdecl
= s
->isStorageClassDeclaration())
399 sdecl
->stc
|= stc
& STClocal
;
402 s
->addMember(sc2
, sds
);
409 Scope
*StorageClassDeclaration::newScope(Scope
*sc
)
411 StorageClass scstc
= sc
->stc
;
413 /* These sets of storage classes are mutually exclusive,
414 * so choose the innermost or most recent one.
416 if (stc
& (STCauto
| STCscope
| STCstatic
| STCextern
| STCmanifest
))
417 scstc
&= ~(STCauto
| STCscope
| STCstatic
| STCextern
| STCmanifest
);
418 if (stc
& (STCauto
| STCscope
| STCstatic
| STCtls
| STCmanifest
| STCgshared
))
419 scstc
&= ~(STCauto
| STCscope
| STCstatic
| STCtls
| STCmanifest
| STCgshared
);
420 if (stc
& (STCconst
| STCimmutable
| STCmanifest
))
421 scstc
&= ~(STCconst
| STCimmutable
| STCmanifest
);
422 if (stc
& (STCgshared
| STCshared
| STCtls
))
423 scstc
&= ~(STCgshared
| STCshared
| STCtls
);
424 if (stc
& (STCsafe
| STCtrusted
| STCsystem
))
425 scstc
&= ~(STCsafe
| STCtrusted
| STCsystem
);
427 //printf("scstc = x%llx\n", scstc);
429 return createNewScope(sc
, scstc
, sc
->linkage
, sc
->cppmangle
,
430 sc
->protection
, sc
->explicitProtection
, sc
->aligndecl
,
434 /********************************* DeprecatedDeclaration ****************************/
436 DeprecatedDeclaration::DeprecatedDeclaration(Expression
*msg
, Dsymbols
*decl
)
437 : StorageClassDeclaration(STCdeprecated
, decl
)
443 Dsymbol
*DeprecatedDeclaration::syntaxCopy(Dsymbol
*s
)
446 return new DeprecatedDeclaration(msg
->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl
));
450 * Provides a new scope with `STCdeprecated` and `Scope.depdecl` set
452 * Calls `StorageClassDeclaration.newScope` (as it must be called or copied
453 * in any function overriding `newScope`), then set the `Scope`'s depdecl.
456 * Always a new scope, to use for this `DeprecatedDeclaration`'s members.
458 Scope
*DeprecatedDeclaration::newScope(Scope
*sc
)
460 Scope
*scx
= StorageClassDeclaration::newScope(sc
);
461 // The enclosing scope is deprecated as well
468 void DeprecatedDeclaration::setScope(Scope
*sc
)
470 //printf("DeprecatedDeclaration::setScope() %p\n", this);
472 Dsymbol::setScope(sc
); // for forward reference
473 return AttribDeclaration::setScope(sc
);
477 * Run the DeprecatedDeclaration's semantic2 phase then its members.
479 * The message set via a `DeprecatedDeclaration` can be either of:
482 * - a static immutable
483 * So we need to call ctfe to resolve it.
484 * Afterward forwards to the members' semantic2.
486 void DeprecatedDeclaration::semantic2(Scope
*sc
)
489 StorageClassDeclaration::semantic2(sc
);
492 const char *DeprecatedDeclaration::getMessage()
494 if (Scope
*sc
= _scope
)
498 sc
= sc
->startCTFE();
499 msg
= ::semantic(msg
, sc
);
500 msg
= resolveProperties(sc
, msg
);
502 msg
= msg
->ctfeInterpret();
504 if (StringExp
*se
= msg
->toStringExp())
505 msgstr
= (char *)se
->string
;
507 msg
->error("compile time constant expected, not '%s'", msg
->toChars());
512 /********************************* LinkDeclaration ****************************/
514 LinkDeclaration::LinkDeclaration(LINK p
, Dsymbols
*decl
)
515 : AttribDeclaration(decl
)
517 //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
518 linkage
= (p
== LINKsystem
) ? Target::systemLinkage() : p
;
521 LinkDeclaration
*LinkDeclaration::create(LINK p
, Dsymbols
*decl
)
523 return new LinkDeclaration(p
, decl
);
526 Dsymbol
*LinkDeclaration::syntaxCopy(Dsymbol
*s
)
529 return new LinkDeclaration(linkage
, Dsymbol::arraySyntaxCopy(decl
));
532 Scope
*LinkDeclaration::newScope(Scope
*sc
)
534 return createNewScope(sc
, sc
->stc
, this->linkage
, sc
->cppmangle
,
535 sc
->protection
, sc
->explicitProtection
, sc
->aligndecl
,
539 const char *LinkDeclaration::toChars()
544 /********************************* CPPMangleDeclaration ****************************/
546 CPPMangleDeclaration::CPPMangleDeclaration(CPPMANGLE p
, Dsymbols
*decl
)
547 : AttribDeclaration(decl
)
549 //printf("CPPMangleDeclaration(cppmangle = %d, decl = %p)\n", p, decl);
553 Dsymbol
*CPPMangleDeclaration::syntaxCopy(Dsymbol
*s
)
556 return new CPPMangleDeclaration(cppmangle
, Dsymbol::arraySyntaxCopy(decl
));
559 Scope
*CPPMangleDeclaration::newScope(Scope
*sc
)
561 return createNewScope(sc
, sc
->stc
, LINKcpp
, this->cppmangle
,
562 sc
->protection
, sc
->explicitProtection
, sc
->aligndecl
,
566 const char *CPPMangleDeclaration::toChars()
571 /********************************* ProtDeclaration ****************************/
575 * loc = source location of attribute token
576 * p = protection attribute data
577 * decl = declarations which are affected by this protection attribute
579 ProtDeclaration::ProtDeclaration(Loc loc
, Prot p
, Dsymbols
*decl
)
580 : AttribDeclaration(decl
)
583 this->protection
= p
;
584 this->pkg_identifiers
= NULL
;
585 //printf("decl = %p\n", decl);
590 * loc = source location of attribute token
591 * pkg_identifiers = list of identifiers for a qualified package name
592 * decl = declarations which are affected by this protection attribute
594 ProtDeclaration::ProtDeclaration(Loc loc
, Identifiers
* pkg_identifiers
, Dsymbols
*decl
)
595 : AttribDeclaration(decl
)
598 this->protection
.kind
= PROTpackage
;
599 this->protection
.pkg
= NULL
;
600 this->pkg_identifiers
= pkg_identifiers
;
603 Dsymbol
*ProtDeclaration::syntaxCopy(Dsymbol
*s
)
606 if (protection
.kind
== PROTpackage
)
607 return new ProtDeclaration(this->loc
, pkg_identifiers
, Dsymbol::arraySyntaxCopy(decl
));
609 return new ProtDeclaration(this->loc
, protection
, Dsymbol::arraySyntaxCopy(decl
));
612 Scope
*ProtDeclaration::newScope(Scope
*sc
)
616 return createNewScope(sc
, sc
->stc
, sc
->linkage
, sc
->cppmangle
,
617 this->protection
, 1, sc
->aligndecl
,
621 void ProtDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sds
)
626 Package::resolve(pkg_identifiers
, &tmp
, NULL
);
627 protection
.pkg
= tmp
? tmp
->isPackage() : NULL
;
628 pkg_identifiers
= NULL
;
631 if (protection
.kind
== PROTpackage
&& protection
.pkg
&& sc
->_module
)
633 Module
*m
= sc
->_module
;
634 Package
* pkg
= m
->parent
? m
->parent
->isPackage() : NULL
;
635 if (!pkg
|| !protection
.pkg
->isAncestorPackageOf(pkg
))
636 error("does not bind to one of ancestor packages of module '%s'",
637 m
->toPrettyChars(true));
640 return AttribDeclaration::addMember(sc
, sds
);
643 const char *ProtDeclaration::kind() const
645 return "protection attribute";
648 const char *ProtDeclaration::toPrettyChars(bool)
650 assert(protection
.kind
> PROTundefined
);
654 protectionToBuffer(&buf
, protection
);
656 return buf
.extractString();
659 /********************************* AlignDeclaration ****************************/
661 AlignDeclaration::AlignDeclaration(Loc loc
, Expression
*ealign
, Dsymbols
*decl
)
662 : AttribDeclaration(decl
)
665 this->ealign
= ealign
;
669 Dsymbol
*AlignDeclaration::syntaxCopy(Dsymbol
*s
)
672 return new AlignDeclaration(loc
,
673 ealign
->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl
));
676 Scope
*AlignDeclaration::newScope(Scope
*sc
)
678 return createNewScope(sc
, sc
->stc
, sc
->linkage
, sc
->cppmangle
,
679 sc
->protection
, sc
->explicitProtection
, this,
683 void AlignDeclaration::semantic2(Scope
*sc
)
686 AttribDeclaration::semantic2(sc
);
689 structalign_t
AlignDeclaration::getAlignment(Scope
*sc
)
695 return salign
= STRUCTALIGN_DEFAULT
;
697 sc
= sc
->startCTFE();
698 ealign
= ::semantic(ealign
, sc
);
699 ealign
= resolveProperties(sc
, ealign
);
701 ealign
= ealign
->ctfeInterpret();
703 if (ealign
->op
== TOKerror
)
704 return salign
= STRUCTALIGN_DEFAULT
;
706 Type
*tb
= ealign
->type
->toBasetype();
707 sinteger_t n
= ealign
->toInteger();
709 if (n
< 1 || n
& (n
- 1) || STRUCTALIGN_DEFAULT
< n
|| !tb
->isintegral())
711 ::error(loc
, "alignment must be an integer positive power of 2, not %s", ealign
->toChars());
712 return salign
= STRUCTALIGN_DEFAULT
;
715 return salign
= (structalign_t
)n
;
718 /********************************* AnonDeclaration ****************************/
720 AnonDeclaration::AnonDeclaration(Loc loc
, bool isunion
, Dsymbols
*decl
)
721 : AttribDeclaration(decl
)
724 this->isunion
= isunion
;
726 this->anonoffset
= 0;
727 this->anonstructsize
= 0;
728 this->anonalignsize
= 0;
731 Dsymbol
*AnonDeclaration::syntaxCopy(Dsymbol
*s
)
734 return new AnonDeclaration(loc
, isunion
, Dsymbol::arraySyntaxCopy(decl
));
737 void AnonDeclaration::setScope(Scope
*sc
)
739 //printf("AnonDeclaration::setScope() %p\n", this);
741 Dsymbol::setScope(sc
);
742 AttribDeclaration::setScope(sc
);
745 void AnonDeclaration::semantic(Scope
*sc
)
747 //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
751 Dsymbol
*p
= sc
->parent
->pastMixin();
752 AggregateDeclaration
*ad
= p
->isAggregateDeclaration();
755 ::error(loc
, "%s can only be a part of an aggregate, not %s %s",
756 kind(), p
->kind(), p
->toChars());
763 sc
->stc
&= ~(STCauto
| STCscope
| STCstatic
| STCtls
| STCgshared
);
764 sc
->inunion
= isunion
;
767 for (size_t i
= 0; i
< decl
->dim
; i
++)
769 Dsymbol
*s
= (*decl
)[i
];
776 void AnonDeclaration::setFieldOffset(AggregateDeclaration
*ad
, unsigned *poffset
, bool isunion
)
778 //printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this);
782 /* This works by treating an AnonDeclaration as an aggregate 'member',
783 * so in order to place that member we need to compute the member's
784 * size and alignment.
787 size_t fieldstart
= ad
->fields
.dim
;
789 /* Hackishly hijack ad's structsize and alignsize fields
790 * for use in our fake anon aggregate member.
792 unsigned savestructsize
= ad
->structsize
;
793 unsigned savealignsize
= ad
->alignsize
;
798 for (size_t i
= 0; i
< decl
->dim
; i
++)
800 Dsymbol
*s
= (*decl
)[i
];
801 s
->setFieldOffset(ad
, &offset
, this->isunion
);
806 /* Bugzilla 13613: If the fields in this->members had been already
807 * added in ad->fields, just update *poffset for the subsequent
808 * field offset calculation.
810 if (fieldstart
== ad
->fields
.dim
)
812 ad
->structsize
= savestructsize
;
813 ad
->alignsize
= savealignsize
;
814 *poffset
= ad
->structsize
;
818 anonstructsize
= ad
->structsize
;
819 anonalignsize
= ad
->alignsize
;
820 ad
->structsize
= savestructsize
;
821 ad
->alignsize
= savealignsize
;
823 // 0 sized structs are set to 1 byte
824 // TODO: is this corect hebavior?
825 if (anonstructsize
== 0)
832 structalign_t alignment
= _scope
->alignment();
834 /* Given the anon 'member's size and alignment,
835 * go ahead and place it.
837 anonoffset
= AggregateDeclaration::placeField(
839 anonstructsize
, anonalignsize
, alignment
,
840 &ad
->structsize
, &ad
->alignsize
,
843 // Add to the anon fields the base offset of this anonymous aggregate
844 //printf("anon fields, anonoffset = %d\n", anonoffset);
845 for (size_t i
= fieldstart
; i
< ad
->fields
.dim
; i
++)
847 VarDeclaration
*v
= ad
->fields
[i
];
848 //printf("\t[%d] %s %d\n", i, v->toChars(), v->offset);
849 v
->offset
+= anonoffset
;
854 const char *AnonDeclaration::kind() const
856 return (isunion
? "anonymous union" : "anonymous struct");
859 /********************************* PragmaDeclaration ****************************/
861 PragmaDeclaration::PragmaDeclaration(Loc loc
, Identifier
*ident
, Expressions
*args
, Dsymbols
*decl
)
862 : AttribDeclaration(decl
)
869 Dsymbol
*PragmaDeclaration::syntaxCopy(Dsymbol
*s
)
871 //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars());
873 return new PragmaDeclaration(loc
, ident
,
874 Expression::arraySyntaxCopy(args
),
875 Dsymbol::arraySyntaxCopy(decl
));
878 Scope
*PragmaDeclaration::newScope(Scope
*sc
)
880 if (ident
== Id::Pinline
)
882 PINLINE inlining
= PINLINEdefault
;
883 if (!args
|| args
->dim
== 0)
884 inlining
= PINLINEdefault
;
885 else if (args
->dim
!= 1)
887 error("one boolean expression expected for pragma(inline), not %d", args
->dim
);
889 (*args
)[0] = new ErrorExp();
893 Expression
*e
= (*args
)[0];
895 if (e
->op
!= TOKint64
|| !e
->type
->equals(Type::tbool
))
897 if (e
->op
!= TOKerror
)
899 error("pragma(inline, true or false) expected, not %s", e
->toChars());
900 (*args
)[0] = new ErrorExp();
903 else if (e
->isBool(true))
904 inlining
= PINLINEalways
;
905 else if (e
->isBool(false))
906 inlining
= PINLINEnever
;
909 return createNewScope(sc
, sc
->stc
, sc
->linkage
, sc
->cppmangle
,
910 sc
->protection
, sc
->explicitProtection
, sc
->aligndecl
,
916 static unsigned setMangleOverride(Dsymbol
*s
, char *sym
)
918 AttribDeclaration
*ad
= s
->isAttribDeclaration();
922 Dsymbols
*decls
= ad
->include(NULL
, NULL
);
923 unsigned nestedCount
= 0;
925 if (decls
&& decls
->dim
)
926 for (size_t i
= 0; i
< decls
->dim
; ++i
)
927 nestedCount
+= setMangleOverride((*decls
)[i
], sym
);
931 else if (s
->isFuncDeclaration() || s
->isVarDeclaration())
933 s
->isDeclaration()->mangleOverride
= sym
;
940 void PragmaDeclaration::semantic(Scope
*sc
)
942 // Should be merged with PragmaStatement
944 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
945 if (ident
== Id::msg
)
949 for (size_t i
= 0; i
< args
->dim
; i
++)
951 Expression
*e
= (*args
)[i
];
953 sc
= sc
->startCTFE();
954 e
= ::semantic(e
, sc
);
955 e
= resolveProperties(sc
, e
);
958 // pragma(msg) is allowed to contain types as well as expressions
959 e
= ctfeInterpretForPragmaMsg(e
);
960 if (e
->op
== TOKerror
)
962 errorSupplemental(loc
, "while evaluating pragma(msg, %s)", (*args
)[i
]->toChars());
965 StringExp
*se
= e
->toStringExp();
969 fprintf(stderr
, "%.*s", (int)se
->len
, (char *)se
->string
);
972 fprintf(stderr
, "%s", e
->toChars());
974 fprintf(stderr
, "\n");
978 else if (ident
== Id::lib
)
980 if (!args
|| args
->dim
!= 1)
981 error("string expected for library name");
984 Expression
*e
= (*args
)[0];
986 sc
= sc
->startCTFE();
987 e
= ::semantic(e
, sc
);
988 e
= resolveProperties(sc
, e
);
991 e
= e
->ctfeInterpret();
993 if (e
->op
== TOKerror
)
995 StringExp
*se
= e
->toStringExp();
997 error("string expected for library name, not '%s'", e
->toChars());
1000 char *name
= (char *)mem
.xmalloc(se
->len
+ 1);
1001 memcpy(name
, se
->string
, se
->len
);
1003 if (global
.params
.verbose
)
1004 message("library %s", name
);
1005 if (global
.params
.moduleDeps
&& !global
.params
.moduleDepsFile
)
1007 OutBuffer
*ob
= global
.params
.moduleDeps
;
1008 Module
*imod
= sc
->instantiatingModule();
1009 ob
->writestring("depsLib ");
1010 ob
->writestring(imod
->toPrettyChars());
1011 ob
->writestring(" (");
1012 escapePath(ob
, imod
->srcfile
->toChars());
1013 ob
->writestring(") : ");
1014 ob
->writestring((char *) name
);
1022 else if (ident
== Id::startaddress
)
1024 if (!args
|| args
->dim
!= 1)
1025 error("function name expected for start address");
1029 * resolveProperties and ctfeInterpret call are not necessary.
1031 Expression
*e
= (*args
)[0];
1033 sc
= sc
->startCTFE();
1034 e
= ::semantic(e
, sc
);
1038 Dsymbol
*sa
= getDsymbol(e
);
1039 if (!sa
|| !sa
->isFuncDeclaration())
1040 error("function name expected for start address, not '%s'", e
->toChars());
1044 else if (ident
== Id::Pinline
)
1048 else if (ident
== Id::mangle
)
1051 args
= new Expressions();
1054 error("string expected for mangled name");
1056 (*args
)[0] = new ErrorExp(); // error recovery
1060 Expression
*e
= (*args
)[0];
1061 e
= ::semantic(e
, sc
);
1062 e
= e
->ctfeInterpret();
1064 if (e
->op
== TOKerror
)
1067 StringExp
*se
= e
->toStringExp();
1070 error("string expected for mangled name, not '%s'", e
->toChars());
1075 error("zero-length string not allowed for mangled name");
1080 error("mangled name characters can only be of type char");
1084 /* Note: D language specification should not have any assumption about backend
1085 * implementation. Ideally pragma(mangle) can accept a string of any content.
1087 * Therefore, this validation is compiler implementation specific.
1089 for (size_t i
= 0; i
< se
->len
; )
1091 utf8_t
*p
= (utf8_t
*)se
->string
;
1095 if ((c
>= 'A' && c
<= 'Z') ||
1096 (c
>= 'a' && c
<= 'z') ||
1097 (c
>= '0' && c
<= '9') ||
1098 (c
!= 0 && strchr("$%().:?@[]_", c
)))
1105 error("char 0x%02x not allowed in mangled name", c
);
1110 if (const char* msg
= utf_decodeChar((utf8_t
*)se
->string
, se
->len
, &i
, &c
))
1118 error("char 0x%04x not allowed in mangled name", c
);
1123 else if (global
.params
.ignoreUnsupportedPragmas
)
1125 if (global
.params
.verbose
)
1127 /* Print unrecognized pragmas
1130 buf
.writestring(ident
->toChars());
1133 for (size_t i
= 0; i
< args
->dim
; i
++)
1135 Expression
*e
= (*args
)[i
];
1137 sc
= sc
->startCTFE();
1138 e
= ::semantic(e
, sc
);
1139 e
= resolveProperties(sc
, e
);
1142 e
= e
->ctfeInterpret();
1144 buf
.writestring(" (");
1147 buf
.writestring(e
->toChars());
1152 message("pragma %s", buf
.peekString());
1157 error("unrecognized pragma(%s)", ident
->toChars());
1162 Scope
*sc2
= newScope(sc
);
1164 for (size_t i
= 0; i
< decl
->dim
; i
++)
1166 Dsymbol
*s
= (*decl
)[i
];
1170 if (ident
== Id::mangle
)
1172 assert(args
&& args
->dim
== 1);
1173 if (StringExp
*se
= (*args
)[0]->toStringExp())
1175 char *name
= (char *)mem
.xmalloc(se
->len
+ 1);
1176 memcpy(name
, se
->string
, se
->len
);
1179 unsigned cnt
= setMangleOverride(s
, name
);
1181 error("can only apply to a single declaration");
1194 error("pragma is missing closing ';'");
1195 goto Ldecl
; // do them anyway, to avoid segfaults.
1199 const char *PragmaDeclaration::kind() const
1204 /********************************* ConditionalDeclaration ****************************/
1206 ConditionalDeclaration::ConditionalDeclaration(Condition
*condition
, Dsymbols
*decl
, Dsymbols
*elsedecl
)
1207 : AttribDeclaration(decl
)
1209 //printf("ConditionalDeclaration::ConditionalDeclaration()\n");
1210 this->condition
= condition
;
1211 this->elsedecl
= elsedecl
;
1214 Dsymbol
*ConditionalDeclaration::syntaxCopy(Dsymbol
*s
)
1217 return new ConditionalDeclaration(condition
->syntaxCopy(),
1218 Dsymbol::arraySyntaxCopy(decl
),
1219 Dsymbol::arraySyntaxCopy(elsedecl
));
1222 bool ConditionalDeclaration::oneMember(Dsymbol
**ps
, Identifier
*ident
)
1224 //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
1227 Dsymbols
*d
= condition
->include(NULL
, NULL
) ? decl
: elsedecl
;
1228 return Dsymbol::oneMembers(d
, ps
, ident
);
1232 bool res
= (Dsymbol::oneMembers( decl
, ps
, ident
) && *ps
== NULL
&&
1233 Dsymbol::oneMembers(elsedecl
, ps
, ident
) && *ps
== NULL
);
1239 // Decide if 'then' or 'else' code should be included
1241 Dsymbols
*ConditionalDeclaration::include(Scope
*sc
, ScopeDsymbol
*sds
)
1243 //printf("ConditionalDeclaration::include(sc = %p) _scope = %p\n", sc, _scope);
1245 return condition
->include(_scope
? _scope
: sc
, sds
) ? decl
: elsedecl
;
1248 void ConditionalDeclaration::setScope(Scope
*sc
)
1250 Dsymbols
*d
= include(sc
, NULL
);
1252 //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
1255 for (size_t i
= 0; i
< d
->dim
; i
++)
1257 Dsymbol
*s
= (*d
)[i
];
1263 void ConditionalDeclaration::addComment(const utf8_t
*comment
)
1265 /* Because addComment is called by the parser, if we called
1266 * include() it would define a version before it was used.
1267 * But it's no problem to drill down to both decl and elsedecl,
1268 * so that's the workaround.
1275 for (int j
= 0; j
< 2; j
++)
1279 for (size_t i
= 0; i
< d
->dim
; i
++)
1281 Dsymbol
*s
= (*d
)[i
];
1282 //printf("ConditionalDeclaration::addComment %s\n", s->toChars());
1283 s
->addComment(comment
);
1291 /***************************** StaticIfDeclaration ****************************/
1293 StaticIfDeclaration::StaticIfDeclaration(Condition
*condition
,
1294 Dsymbols
*decl
, Dsymbols
*elsedecl
)
1295 : ConditionalDeclaration(condition
, decl
, elsedecl
)
1297 //printf("StaticIfDeclaration::StaticIfDeclaration()\n");
1302 Dsymbol
*StaticIfDeclaration::syntaxCopy(Dsymbol
*s
)
1305 return new StaticIfDeclaration(condition
->syntaxCopy(),
1306 Dsymbol::arraySyntaxCopy(decl
),
1307 Dsymbol::arraySyntaxCopy(elsedecl
));
1310 /****************************************
1311 * Different from other AttribDeclaration subclasses, include() call requires
1312 * the completion of addMember and setScope phases.
1314 Dsymbols
*StaticIfDeclaration::include(Scope
*sc
, ScopeDsymbol
*)
1316 //printf("StaticIfDeclaration::include(sc = %p) _scope = %p\n", sc, _scope);
1318 if (condition
->inc
== 0)
1320 assert(scopesym
); // addMember is already done
1321 assert(_scope
); // setScope is already done
1323 Dsymbols
*d
= ConditionalDeclaration::include(_scope
, scopesym
);
1325 if (d
&& !addisdone
)
1327 // Add members lazily.
1328 for (size_t i
= 0; i
< d
->dim
; i
++)
1330 Dsymbol
*s
= (*d
)[i
];
1331 s
->addMember(_scope
, scopesym
);
1334 // Set the member scopes lazily.
1335 for (size_t i
= 0; i
< d
->dim
; i
++)
1337 Dsymbol
*s
= (*d
)[i
];
1338 s
->setScope(_scope
);
1347 return ConditionalDeclaration::include(sc
, scopesym
);
1351 void StaticIfDeclaration::addMember(Scope
*, ScopeDsymbol
*sds
)
1353 //printf("StaticIfDeclaration::addMember() '%s'\n", toChars());
1354 /* This is deferred until the condition evaluated later (by the include() call),
1355 * so that expressions in the condition can refer to declarations
1356 * in the same scope, such as:
1358 * template Foo(int i)
1360 * const int j = i + 1;
1361 * static if (j == 3)
1365 this->scopesym
= sds
;
1368 void StaticIfDeclaration::importAll(Scope
*)
1370 // do not evaluate condition before semantic pass
1373 void StaticIfDeclaration::setScope(Scope
*sc
)
1375 // do not evaluate condition before semantic pass
1377 // But do set the scope, in case we need it for forward referencing
1378 Dsymbol::setScope(sc
);
1381 void StaticIfDeclaration::semantic(Scope
*sc
)
1383 AttribDeclaration::semantic(sc
);
1386 const char *StaticIfDeclaration::kind() const
1391 /***************************** CompileDeclaration *****************************/
1393 // These are mixin declarations, like mixin("int x");
1395 CompileDeclaration::CompileDeclaration(Loc loc
, Expression
*exp
)
1396 : AttribDeclaration(NULL
)
1398 //printf("CompileDeclaration(loc = %d)\n", loc.linnum);
1401 this->scopesym
= NULL
;
1402 this->compiled
= false;
1405 Dsymbol
*CompileDeclaration::syntaxCopy(Dsymbol
*)
1407 //printf("CompileDeclaration::syntaxCopy('%s')\n", toChars());
1408 return new CompileDeclaration(loc
, exp
->syntaxCopy());
1411 void CompileDeclaration::addMember(Scope
*, ScopeDsymbol
*sds
)
1413 //printf("CompileDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\n", sc, sds, memnum);
1414 this->scopesym
= sds
;
1417 void CompileDeclaration::setScope(Scope
*sc
)
1419 Dsymbol::setScope(sc
);
1422 void CompileDeclaration::compileIt(Scope
*sc
)
1424 //printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars());
1425 sc
= sc
->startCTFE();
1426 exp
= ::semantic(exp
, sc
);
1427 exp
= resolveProperties(sc
, exp
);
1430 if (exp
->op
!= TOKerror
)
1432 Expression
*e
= exp
->ctfeInterpret();
1433 if (e
->op
== TOKerror
) // Bugzilla 15974
1435 StringExp
*se
= e
->toStringExp();
1437 exp
->error("argument to mixin must be a string, not (%s) of type %s", exp
->toChars(), exp
->type
->toChars());
1440 se
= se
->toUTF8(sc
);
1441 unsigned errors
= global
.errors
;
1442 Parser
p(loc
, sc
->_module
, (utf8_t
*)se
->string
, se
->len
, 0);
1445 decl
= p
.parseDeclDefs(0);
1446 if (p
.token
.value
!= TOKeof
)
1447 exp
->error("incomplete mixin declaration (%s)", se
->toChars());
1450 assert(global
.errors
!= errors
);
1457 void CompileDeclaration::semantic(Scope
*sc
)
1459 //printf("CompileDeclaration::semantic()\n");
1464 AttribDeclaration::addMember(sc
, scopesym
);
1469 for (size_t i
= 0; i
< decl
->dim
; i
++)
1471 Dsymbol
*s
= (*decl
)[i
];
1472 s
->setScope(_scope
);
1476 AttribDeclaration::semantic(sc
);
1479 const char *CompileDeclaration::kind() const
1484 /***************************** UserAttributeDeclaration *****************************/
1486 UserAttributeDeclaration::UserAttributeDeclaration(Expressions
*atts
, Dsymbols
*decl
)
1487 : AttribDeclaration(decl
)
1489 //printf("UserAttributeDeclaration()\n");
1493 Dsymbol
*UserAttributeDeclaration::syntaxCopy(Dsymbol
*s
)
1495 //printf("UserAttributeDeclaration::syntaxCopy('%s')\n", toChars());
1497 return new UserAttributeDeclaration(
1498 Expression::arraySyntaxCopy(this->atts
),
1499 Dsymbol::arraySyntaxCopy(decl
));
1502 Scope
*UserAttributeDeclaration::newScope(Scope
*sc
)
1505 if (atts
&& atts
->dim
)
1507 // create new one for changes
1509 sc2
->userAttribDecl
= this;
1514 void UserAttributeDeclaration::setScope(Scope
*sc
)
1516 //printf("UserAttributeDeclaration::setScope() %p\n", this);
1518 Dsymbol::setScope(sc
); // for forward reference of UDAs
1520 return AttribDeclaration::setScope(sc
);
1523 void UserAttributeDeclaration::semantic(Scope
*sc
)
1525 //printf("UserAttributeDeclaration::semantic() %p\n", this);
1526 if (decl
&& !_scope
)
1527 Dsymbol::setScope(sc
); // for function local symbols
1529 return AttribDeclaration::semantic(sc
);
1532 static void udaExpressionEval(Scope
*sc
, Expressions
*exps
)
1534 for (size_t i
= 0; i
< exps
->dim
; i
++)
1536 Expression
*e
= (*exps
)[i
];
1539 e
= ::semantic(e
, sc
);
1540 if (definitelyValueParameter(e
))
1541 e
= e
->ctfeInterpret();
1542 if (e
->op
== TOKtuple
)
1544 TupleExp
*te
= (TupleExp
*)e
;
1545 udaExpressionEval(sc
, te
->exps
);
1552 void UserAttributeDeclaration::semantic2(Scope
*sc
)
1554 if (decl
&& atts
&& atts
->dim
&& _scope
)
1557 udaExpressionEval(sc
, atts
);
1560 AttribDeclaration::semantic2(sc
);
1563 Expressions
*UserAttributeDeclaration::concat(Expressions
*udas1
, Expressions
*udas2
)
1566 if (!udas1
|| udas1
->dim
== 0)
1568 else if (!udas2
|| udas2
->dim
== 0)
1572 /* Create a new tuple that combines them
1573 * (do not append to left operand, as this is a copy-on-write operation)
1575 udas
= new Expressions();
1576 udas
->push(new TupleExp(Loc(), udas1
));
1577 udas
->push(new TupleExp(Loc(), udas2
));
1582 Expressions
*UserAttributeDeclaration::getAttributes()
1584 if (Scope
*sc
= _scope
)
1587 arrayExpressionSemantic(atts
, sc
);
1590 Expressions
*exps
= new Expressions();
1592 exps
->push(new TupleExp(Loc(), userAttribDecl
->getAttributes()));
1593 if (atts
&& atts
->dim
)
1594 exps
->push(new TupleExp(Loc(), atts
));
1599 const char *UserAttributeDeclaration::kind() const
1601 return "UserAttribute";