Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.


Defines declarations of various attributes.
The term 'attribute' refers to things that can apply to a larger scope than a single declaration. Among them are:
  • Alignment (align(8))
  • User defined attributes (@UDA)
  • Function Attributes (@safe)
  • Storage classes (static, __gshared)
  • Mixin declarations (mixin("int x;"))
  • Conditional compilation (static if, static foreach)
  • Linkage (extern(C))
  • Anonymous structs / unions
  • Protection (private, public)
  • Deprecated declarations (@deprecated)

Source attrib.d

abstract class AttribDeclaration: dmd.dsymbol.Dsymbol;
Abstract attribute applied to Dsymbol's used as a common ancestor for storage classes (StorageClassDeclaration), linkage (LinkageDeclaration) and others.
Dsymbols* decl;
Dsymbol's affected by this AttribDeclaration
static Scope* createNewScope(Scope* sc, StorageClass stc, LINK linkage, CPPMANGLE cppmangle, Visibility visibility, int explicitVisibility, AlignDeclaration aligndecl, PragmaDeclaration inlining);
Create a new scope if one or more given attributes are different from the sc's. If the returned scope != sc, the caller should pop the scope after it used.
Scope* newScope(Scope* sc);
A hook point to supply scope for members. addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this.
final void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories);
class StorageClassDeclaration: dmd.attrib.AttribDeclaration;
Storage classes applied to Dsymbols, e.g. const int i;
class DeprecatedDeclaration: dmd.attrib.StorageClassDeclaration;
Deprecation with an additional message applied to Dsymbols, e.g. deprecated("Superseeded by foo") int bar;. (Note that deprecated int bar; is currently represented as a StorageClassDeclaration with STC.deprecated_)
deprecated(<msg>) <decl...>
Expression msg;
deprecation message
const(char)* msgstr;
cached string representation of msg
Scope* newScope(Scope* sc);
Provides a new scope with STC.deprecated_ and Scope.depdecl set
Calls StorageClassDeclaration.newScope (as it must be called or copied in any function overriding newScope), then set the Scope's depdecl.
Always a new scope, to use for this DeprecatedDeclaration's members.
class LinkDeclaration: dmd.attrib.AttribDeclaration;
Linkage attribute applied to Dsymbols, e.g. extern(C) void foo().
extern(<linkage>) <decl...>
LINK linkage;
either explicitly set or default_
class CPPMangleDeclaration: dmd.attrib.AttribDeclaration;
Attribute declaring whether an external aggregate should be mangled as a struct or class in C++, e.g. extern(C++, struct) class C { ... }. This is required for correct name mangling on MSVC targets, see cppmanglewin.d for details.
extern(C++, <cppmangle>) <decl...>
class CPPNamespaceDeclaration: dmd.attrib.AttribDeclaration;
A node to represent an extern(C++) namespace attribute
There are two ways to declarate a symbol as member of a namespace: Nspace and CPPNamespaceDeclaration. The former creates a scope for the symbol, and inject them in the parent scope at the same time. The later, this class, has no semantic implications and is only used for mangling. Additionally, this class allows one to use reserved identifiers (D keywords) in the namespace.
A CPPNamespaceDeclaration can be created from an Identifier (already resolved) or from an Expression, which is CTFE-ed and can be either a TupleExp, in which can additional CPPNamespaceDeclaration nodes are created, or a StringExp.
Note that this class, like Nspace, matches only one identifier part of a namespace. For the namespace "foo::bar", the will be a CPPNamespaceDeclaration with its ident set to "bar", and its namespace field pointing to another CPPNamespaceDeclaration with its ident set to "foo".
Expression exp;
CTFE-able expression, resolving to TupleExp or StringExp
Scope* newScope(Scope* sc);
A copy of the parent scope, with this as namespace and C++ linkage
class VisibilityDeclaration: dmd.attrib.AttribDeclaration;
Visibility declaration for Dsymbols, e.g. public int i;
<visibility> <decl...> or package(<pkg_identifiers>) <decl...> if pkg_identifiers !is null
Visibility visibility;
the visibility
Identifier[] pkg_identifiers;
identifiers for package( or null
@safe this(const ref Loc loc, Visibility visibility, Dsymbols* decl);
Loc loc source location of attribute token
Visibility visibility visibility attribute data
Dsymbols* decl declarations which are affected by this visibility attribute
this(const ref Loc loc, Identifier[] pkg_identifiers, Dsymbols* decl);
Loc loc source location of attribute token
Identifier[] pkg_identifiers list of identifiers for a qualified package name
Dsymbols* decl declarations which are affected by this visibility attribute
class AlignDeclaration: dmd.attrib.AttribDeclaration;
Alignment attribute for aggregates, members and variables.
align(<ealign>) <decl...> or align <decl...> if ealign is null
Expressions* exps;
Expression(s) yielding the desired alignment,
structalign_t salign;
the largest value wins the actual alignment is Unknown until it's either set to the value of ealign or the default if ealign is null ( / an error ocurred)
class AnonDeclaration: dmd.attrib.AttribDeclaration;
An anonymous struct/union (defined by isunion).
bool isunion;
whether it's a union
int sem;
1 if successful semantic()
uint anonoffset;
offset of anonymous struct
uint anonstructsize;
size of anonymous struct
uint anonalignsize;
size of anonymous struct for alignment purposes
class PragmaDeclaration: dmd.attrib.AttribDeclaration;
Pragma applied to Dsymbols, e.g. pragma(inline, true) void foo, but not PragmaStatement's like pragma(msg, "hello");.
pragma(, )
Expressions* args;
parameters of this pragma
class ConditionalDeclaration: dmd.attrib.AttribDeclaration;
A conditional compilation declaration, used for version / debug and specialized for static if.
{ } else { }
Condition condition;
condition deciding whether decl or elsedecl applies
Dsymbols* elsedecl;
array of Dsymbol's for else block
class StaticIfDeclaration: dmd.attrib.ConditionalDeclaration;
` { static if () { } else { } }`
ScopeDsymbol scopesym;
enclosing symbol (e.g. module) where symbols will be inserted
Dsymbols* include(Scope* sc);
Different from other AttribDeclaration subclasses, include() call requires the completion of addMember and setScope phases.
class StaticForeachDeclaration: dmd.attrib.AttribDeclaration;
Static foreach at declaration scope, like: static foreach (i; [0, 1, 2]){ }
StaticForeach sfe;
contains static foreach expansion logic
ScopeDsymbol scopesym;
cached enclosing scope (mimics static if declaration)
bool onStack;
include can be called multiple times, but a static foreach should be expanded at most once. Achieved by caching the result of the first call. We need both cached and cache, because null is a valid value for cache.
class ForwardingAttribDeclaration: dmd.attrib.AttribDeclaration;
Collection of declarations that stores foreach index variables in a local symbol table. Other symbols declared within are forwarded to another scope, like:
static foreach (i; 0 .. 10) // loop variables for different indices do not conflict. { // this body is expanded into 10 ForwardingAttribDeclarations, where i has storage class STC.local mixin("enum x" ~ to!string(i) ~ " = i"); // ok, can access current loop variable }
static foreach (i; 0.. 10) { pragma(msg, mixin("x" ~ to!string(i))); // ok, all 10 symbols are visible as they were forwarded to the global scope }
static assert (!is(typeof(i))); // loop index variable is not visible outside of the static foreach loop
A StaticForeachDeclaration generates one ForwardingAttribDeclaration for each expansion of its body. The AST of the ForwardingAttribDeclaration contains both the `static foreach variables and the respective copy of the static foreach` body. The functionality is achieved by using a ForwardingScopeDsymbol as the parent symbol for the generated declarations.
Scope* newScope(Scope* sc);
Use the ForwardingScopeDsymbol as the parent symbol for members.
class MixinDeclaration: dmd.attrib.AttribDeclaration;
Mixin declarations, like: mixin("int x");
class UserAttributeDeclaration: dmd.attrib.AttribDeclaration;
User defined attributes look like: @foo(args, ...) @(args, ...)
static bool isGNUABITag(Expression e);
Check if the provided expression references core.attribute.gnuAbiTag
This should be called after semantic has been run on the expression. Semantic on UDA happens in semantic2 (see dmd.semantic2).
Expression e Expression to check (usually from UserAttributeDeclaration.atts)
true if the expression references the compiler-recognized gnuAbiTag
static void checkGNUABITag(Dsymbol sym, LINK linkage);
Called from a symbol's semantic to check if gnuAbiTag UDA can be applied to them
Directly emits an error if the UDA doesn't work with this symbol
Dsymbol sym symbol to check for gnuAbiTag
LINK linkage Linkage of the symbol ( or
bool isCoreUda(Dsymbol sym, Identifier ident);
Returns true if the given symbol is a symbol declared in core.attribute and has the given identifier.
This is used to determine if a symbol is a UDA declared in core.attribute.
Dsymbol sym the symbol to check
Identifier ident the name of the expected UDA
int foreachUdaNoSemantic(Dsymbol sym, int delegate(Expression) dg);
Iterates the UDAs attached to the given symbol, without performing semantic analysis.
Use this function instead of foreachUda if semantic analysis of sym is still in progress.
Dsymbol sym the symbol to get the UDAs from
int delegate(Expression) dg called once for each UDA
If dg returns != 0, stops the iteration and returns that value. Otherwise, returns 0.
bool isEnumAttribute(Expression e, Identifier id);
true if the given expression is an enum from core.attribute named id