Go to the first, previous, next, last section, table of contents.

5.4 Declarators

In a declaration (see section 5 Declarations), a declarator declares a single object, function, or type. The optional declaration specifiers (see section 5.2 Declaration Specifiers) describe its type, storage class, and other attributes. A declarator gives it a name and may refine its type with operators such *, as described in Section r.8 of [Stroustrup91]. The following table, from page 132 of [Ellis-Stroustrup90], summarizes these operators.

   Operator     Meaning
   ---------    -----------------
   *            Pointer
   ::*          Pointer to Member
   &            Reference
   []           Array
   ()           Function

The syntax of declarators and abstract declarators is as in C++, except that when declaring a function, a param-qualifier may also declare LSL traits that are expected. See section 6.13 Specifying Higher-Order Functions for the syntax and use of the expects-clause. See section 5.1 Initializers for the syntax of initialization within declarators. See section 6.11 Exceptions for the syntax of exception-decl. See section Class and Namespace Names for the syntax of complete-class-name and complete-namespace-name. See section 5.2.3 Type Specifiers for the syntax of cv-qualifier.

declarator ::= direct-declarator | ptr-operator declarator
direct-declarator ::= id-expression | direct-declarator declarator-qualifier
        | ( declarator )
declarator-qualifier ::= [ [ constant-expression ] ] | param-qualifier
param-qualifier ::= ( [ parameter-declaration-clause ] [ expects-clause ] )
                           [ cv-qualifier-seq ] [ exception-decl ]
id-expression ::= unqualified-id | qualified-id
unqualified-id ::= identifier
        | operator-function-id | conversion-function-id
        | template-instance
qualified-id ::= nested-name-specifier [ template ] unqualified-id
operator-function-id ::= operator C++-operator-symbol
conversion-function-id ::= operator type-specifier-seq [ ptr-operator ]
conversion-type-id ::= type-specifier-seq [ conversion-declarator ]
conversion-declarator ::= ptr-operator [ conversion-declarator ]
ptr-operator ::= * [ cv-qualifier-seq ] | &
      | [ :: ] nested-name-specifier * [ cv-qualifier-seq ]
cv-qualifier-seq ::= cv-qualifier [ cv-qualifier ] ...
abstract-declarator ::= ptr-operator [ abstract-declarator ]
      | direct-abstract-declarator
direct-abstract-declarator ::= [ direct-abstract-declarator ] declarator-qualifier
      | ( abstract-declarator )

The semantics of each of these forms of declarator are described below.

In the context of a declaration, each declarator in a Larch/C++ specification associates a sort with an id-expression. This sort is based on the declared C++ type name, and sort generators are used to deal with the C++ concepts of variables, pointers, etc. With each such sort, there is an LSL trait that gives its meaning. For example, the name Obj[int] is used as the sort for integer objects. An integer object in Larch/C++ is either a global variable (declared as int i or int& i) or a reference parameter (declared as int& i). Note that non-reference parameters in C++ are passed by value, and so are not treated as objects by Larch/C++ (see section 6.2.1 State Functions).

To be more concrete, consider the following table.

Declaration      Name   Its Sort (when used as a global variable)
-------------    ----   -----------------------------------------
int i = 7;       i      Obj[int]

The sort of i, when used as a global variable, is Obj[int], which means that i is an object containing an int. An object may have a value in a given state; typically in Larch/C++ the states of interest are those just before or just after the C++ function being specified. As explained below (see section 6.2.1 State Functions), the value of i in the state before a function call is written i^, and value afterwards is written i'. The sort of both i^ and i' is int.

The semantics of object sorts (such as Obj[int]) are described using the trait MutableObj (see section Formal Model of Mutable Objects), which is instantiated with a value sort (such as int). That is, when a global int variable is declared, Larch/C++ implicitly uses the trait MutableObj(int). Similarly, for a global declaration of a variable of type T, Larch/C++ implicitly uses the trait MutableObj(T). Exceptions to this rule are made for global declarations of structs and classes (see section 5.4.4 Structure and Class Declarations) and arrays (see section 5.4.3 Array Declarations).

The meaning of declarations using operators such as * is explained in the subsections below.

Go to the first, previous, next, last section, table of contents.