dmd.attrib

Defines declarations of various attributes.

Discussion

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)

Authors

Walter Bright

Source: attrib.d

  • Declaration

    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.

    • Declaration

      Dsymbols* decl;

      Dsymbol's affected by this AttribDeclaration

    • Declaration

      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.

    • Declaration

      Scope* newScope(Scope* sc);

      A hook point to supply scope for members. addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this.

    • Declaration

      final void addLocalClass(ClassDeclarations* aclasses);

  • Declaration

    class StorageClassDeclaration: dmd.attrib.AttribDeclaration;

    Storage classes applied to Dsymbols, e.g. const int i;

    Discussion

  • Declaration

    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_)

    Discussion

    deprecated(<msg>) <decl...>

    • msg

      Declaration

      Expression msg;

      deprecation message

    • Declaration

      const(char)* msgstr;

      cached string representation of msg

    • Declaration

      Scope* newScope(Scope* sc);

      Provides a new scope with STC.deprecated_ and Scope.depdecl set

      Discussion

      Calls StorageClassDeclaration.newScope (as it must be called or copied in any function overriding newScope), then set the Scope's depdecl.

      Return Value

      Always a new scope, to use for this DeprecatedDeclaration's members.

  • Declaration

    class LinkDeclaration: dmd.attrib.AttribDeclaration;

    Linkage attribute applied to Dsymbols, e.g. extern(C) void foo().

    Discussion

    extern(<linkage>) <decl...>

    • Declaration

      LINK linkage;

      either explicitly set or default_

  • Declaration

    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.

    Discussion

    extern(C++, <cppmangle>) <decl...>

  • Declaration

    class CPPNamespaceDeclaration: dmd.attrib.AttribDeclaration;

    A node to represent an extern(C++) namespace attribute

    Discussion

    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".

    • exp

      Declaration

      Expression exp;

      CTFE-able expression, resolving to TupleExp or StringExp

    • Declaration

      Scope* newScope(Scope* sc);

      Return Value

      A copy of the parent scope, with this as namespace and C++ linkage

  • Declaration

    class VisibilityDeclaration: dmd.attrib.AttribDeclaration;

    Visibility declaration for Dsymbols, e.g. public int i;

    Discussion

    <visibility> <decl...> or package(<pkg_identifiers>) <decl...> if pkg_identifiers !is null

    • Declaration

      Visibility visibility;

      the visibility

    • Declaration

      Identifier[] pkg_identifiers;

      identifiers for package(foo.bar) or null

    • Declaration

      this(const ref Loc loc, Visibility visibility, Dsymbols* decl);

      Parameters

      Loc loc

      source location of attribute token

      Visibility visibility

      visibility attribute data

      Dsymbols* decl

      declarations which are affected by this visibility attribute

    • Declaration

      this(const ref Loc loc, Identifier[] pkg_identifiers, Dsymbols* decl);

      Parameters

      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

  • Declaration

    class AlignDeclaration: dmd.attrib.AttribDeclaration;

    Alignment attribute for aggregates, members and variables.

    Discussion

    align(<ealign>) <decl...> or align <decl...> if ealign is null

    • Declaration

      Expressions* exps;

      Expression(s) yielding the desired alignment,

    • Declaration

      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)

  • Declaration

    class AnonDeclaration: dmd.attrib.AttribDeclaration;

    An anonymous struct/union (defined by isunion).

    • Declaration

      bool isunion;

      whether it's a union

    • sem

      Declaration

      int sem;

      1 if successful semantic()

    • Declaration

      uint anonoffset;

      offset of anonymous struct

    • Declaration

      uint anonstructsize;

      size of anonymous struct

    • Declaration

      uint anonalignsize;

      size of anonymous struct for alignment purposes

  • Declaration

    class PragmaDeclaration: dmd.attrib.AttribDeclaration;

    Pragma applied to Dsymbols, e.g. pragma(inline, true) void foo, but not PragmaStatement's like pragma(msg, "hello");.

    Discussion

    pragma(, )

    • Declaration

      Expressions* args;

      parameters of this pragma

  • Declaration

    class ConditionalDeclaration: dmd.attrib.AttribDeclaration;

    A conditional compilation declaration, used for version / debug and specialized for static if.

    Discussion

    { } else { }

    • Declaration

      Condition condition;

      condition deciding whether decl or elsedecl applies

    • Declaration

      Dsymbols* elsedecl;

      array of Dsymbol's for else block

  • Declaration

    class StaticIfDeclaration: dmd.attrib.ConditionalDeclaration;

    ` { static if () { } else { } }`

    • Declaration

      ScopeDsymbol scopesym;

      enclosing symbol (e.g. module) where symbols will be inserted

    • Declaration

      Dsymbols* include(Scope* sc);

      Different from other AttribDeclaration subclasses, include() call requires the completion of addMember and setScope phases.

  • Declaration

    class StaticForeachDeclaration: dmd.attrib.AttribDeclaration;

    Static foreach at declaration scope, like: static foreach (i; [0, 1, 2]){ }

    • sfe

      Declaration

      StaticForeach sfe;

      contains static foreach expansion logic

    • Declaration

      ScopeDsymbol scopesym;

      cached enclosing scope (mimics static if declaration)

    • 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.

  • Declaration

    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:

    Discussion

    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.

    • Declaration

      Scope* newScope(Scope* sc);

      Use the ForwardingScopeDsymbol as the parent symbol for members.

    • Declaration

      void addMember(Scope* sc, ScopeDsymbol sds);

      Lazily initializes the scope to forward to.

  • Declaration

    class CompileDeclaration: dmd.attrib.AttribDeclaration;

    Mixin declarations, like: mixin("int x"); https://dlang.org/spec/module.html#mixin-declaration

  • Declaration

    class UserAttributeDeclaration: dmd.attrib.AttribDeclaration;

    User defined attributes look like: @foo(args, ...) @(args, ...)

    • Declaration

      static bool isGNUABITag(Expression e);

      Check if the provided expression references core.attribute.gnuAbiTag

      Discussion

      This should be called after semantic has been run on the expression. Semantic on UDA happens in semantic2 (see dmd.semantic2).

      Parameters

      Expression e

      Expression to check (usually from UserAttributeDeclaration.atts)

      Return Value

      true if the expression references the compiler-recognized gnuAbiTag

    • Declaration

      static void checkGNUABITag(Dsymbol sym, LINK linkage);

      Called from a symbol's semantic to check if gnuAbiTag UDA can be applied to them

      Discussion

      Directly emits an error if the UDA doesn't work with this symbol

      Parameters

      Dsymbol sym

      symbol to check for gnuAbiTag

      LINK linkage

      Linkage of the symbol (Declaration.link or sc.link)

  • Declaration

    bool isCoreUda(Dsymbol sym, Identifier ident);

    Returns true if the given symbol is a symbol declared in core.attribute and has the given identifier.

    Discussion

    This is used to determine if a symbol is a UDA declared in core.attribute.

    Parameters

    Dsymbol sym

    the symbol to check

    Identifier ident

    the name of the expected UDA

  • Declaration

    int foreachUda(Dsymbol sym, Scope* sc, int delegate(Expression) dg);

    Iterates the UDAs attached to the given symbol.

    Discussion

    If dg returns != 0, it will stop the iteration and return that value, otherwise it will return 0.

    Parameters

    Dsymbol sym

    the symbol to get the UDAs from

    Scope* sc

    scope to use for semantic analysis of UDAs

    int delegate(Expression) dg

    called once for each UDA. If dg returns != 0, it will stop the iteration and return that value, otherwise it will return 0.

  • )