Attributes in Chapel¶
Overview¶
Attributes are a mechanism to mark symbols with additional information. This information can then be used when processing the abstract syntax tree (AST) representation of the source code.
Generally, an attribute in Chapel is specified above a symbol declaration with
an @
followed by an identifier that specifies the attribute name. A list of
arguments can be enclosed in parentheses ()
. Arguments can be named or
specified in order, but mixing the use of named and unnamed arguments in the
same attribute is not supported. Note that whitespace is not allowed
between the @
and the identifier.
Attributes in Chapel are currently used to indicate feature stability and to exclude features from documentation when using chpldoc. The syntax of attributes in Chapel is inspired by Rust’s, and includes the ability to specify a tool name for an attribute.
Here are examples of what an attribute might look like:
// example of an attribute without a tool name
@attributeName(arg1="value", arg2=1, arg3=1.0, arg4=true, arg5=1..10)
proc foo() { }
// example of an attribute with a tool name
@toolName.attributeName(arg1="value", arg2=1, arg3=true)
proc foo() { }
Limitations¶
Multiple attributes can be applied to the same symbol, however an individual attribute can only be applied once to a symbol.
When both attributes and pragmas apply to a symbol, the attribute must be placed after any pragmas.
Top-level Attributes¶
An attribute without any specified tool name is called top-level. Top-level attributes are assumed to be language features and are reserved for use by the Chapel development team. Any unrecognized attributes will be reported to the user as an error. Attribute arguments can be string, bool, int, real, or range literals.
Tool names¶
Tool names allow the Chapel compiler to distinguish between attributes that it
should process and attributes that should be passed to other tools. By default,
all tool names other than chpldoc
will be reported to the user as a warning.
Developers of other tools, such as formatters or linters, are free to design
their own attributes so long as they prefix them with a tool name. It is
recommended but not required that the tool name aligns with the tool binary
name. As an example, see the @chpldoc.nodoc attribute,
which is used by the chpldoc
tool to suppress documentation for a symbol.
The tool name chpldoc
precedes the attribute name nodoc
, which takes no
arguments.
Tool names other than chpldoc
are not recognized by the chpl
compiler
and it will issue a warning to the user when it encounters a name it doesn’t
recognize. This warning is on by default as a conservative approach to catching
misspellings of tool names, like @chplldoc, or misplaced dots ‘.’ in attribute
names as in @un.stable. To suppress warnings for a particular tool name,
compile with the flag --using-attribute-toolname=<toolname>
. To suppress
warnings for all unknown tool names, compile with the flag
--no-warn-unknown-attribute-toolname
.
The tool name chpldoc
is recognized without additional flags because the
tool is developed and distributed with the Chapel language. The list of known
tool names may be expanded in the future. The tool name chpl
is reserved
for future use by the Chapel development team.
Implemented Attributes¶
Attributes are currently implemented in the following areas:
Stability Attributes¶
Note
The API for stability attributes is still under development and may change in a future release.
// ways to use @deprecated
@deprecated
proc foo() {}
@deprecated("foo is deprecated, please use bar")
proc foo() {}
@deprecated(since="1.30", notes="foo is deprecated", suggestion="use bar")
proc foo() {}
// ways to use @unstable
@unstable
proc foo() {}
@unstable("foo is unstable")
proc foo() {}
@unstable(category="experimental", issue="1234", reason="testing a new feature")
proc foo() {}
// ways to use @stable
@stable(since="1.30")
proc foo() {}
@stable("1.30")
proc bar() {}
Note
The @stable
attribute is currently not implemented. The compiler will
parse it, but it will not have any effect.
Other Attributes¶
@chpldoc.nodoc
is used to prevent a symbol from being included in documentation generated by chpldoc. This attribute replaces the previous method of usingpragma "no doc"
to suppress documentation for a symbol. When converting existing code, note that@chpldoc.nodoc
must be placed after any remaining pragmas assigned to the symbol.// prevent the entire module from being documented @chpldoc.nodoc module M { } // valid placement of @chpldoc.nodoc pragma "always RVF" @chpldoc.nodoc proc foo() { } // invalid placement of @chpldoc.nodoc @chpldoc.nodoc pragma "always RVF" proc foo() { }
@llvm.assertVectorized
is an experimental attribute which can be applied to all statement-level loops. When used on a loop, it applies a post-codegen check for the LLVM backend to ensure the loop was vectorized. If the loop is not vectorized, a compile time warning will be emitted. This is based on LLVM’s definition for a successful vectorization and the result may not actually contain vector instructions. Note that this attribute is currently only meaningful onfor
andforeach
loops.@llvm.assertVectorized() foreach a in A { ... }; // warns if this is not vectorizable
@llvm.metadata
is an experimental attribute which can be used to adjust the code generation when using the LLVM backend. It can take any number of arguments which are either string literals or 2-tuples (1-tuples of string literals can be used as a convenience). The first element of the 2-tuple must be a string literal and the second element can be a string literal, an int literal, a bool literal, or another valid 2-tuple. The arguments are encoded directly into LLVM Metadata. Note that this attribute is currently only meaningful onfor
andforeach
loops.@llvm.metadata( ("llvm.loop.vectorize.enable", true), // becomes !{!"llvm.loop.vectorize.enable", i1 true} ("llvm.loop.vectorize.width", 4) // becomes !{!"llvm.loop.vectorize.width", i64 4} ) foreach a in A { ... };
Future Work and Design Discussions¶
Planned work for attributes includes:
deprecate and replace the use of
pragma "no doc"
with@chpldoc.nodoc
as the primary means to omit documentation for a symbolconvert
pragma "always RVF"
into an attribute, possibly@chpl.alwaysRvf
allow any order of pragmas and attributes
lock in the argument names and types for stability attributes and use them to improve the compiler’s messages regarding symbol stability