Guide to the HP Structure Definition Language


Previous Contents Index


Chapter 4
HP SDL Declarations

This chapter describes the function and format of each of the following HP SDL declarations:

HP SDL declarations are composed of the language elements described in Chapter 3. The output generated by each HP SDL declaration depends on which back end is used for the translation.

Online examples of output files for each language are available by processing the HP SDL source file EXAMPLE.SDL in SDL$EXAMPLES. Appendix B provides translation summaries for each output language.


MODULE Declaration

The following sections describe the function and format of a MODULE declaration.

4.1 MODULE Description

A MODULE declaration groups all related symbols and data structures. All declarations (other than local symbol assignments and local and output comments) must occur within a module, which is delimited by the MODULE and END_MODULE keywords. A HP SDL source file may contain multiple MODULE declarations, but modules may not be nested.

You must specify a module name on the MODULE declaration; this name corresponds to the name of a macro or module in a given output language. ( Section 3.1 describes the syntax for names.) For example:


MODULE $modef; 

This declaration generates the beginning of the declaration for the macro or module named $modef.

You can use the IDENT option on a MODULE declaration to pass a version number or other information that must be enclosed in quotation marks (" ") to the output file. For example:


MODULE params IDENT "V2.0"; 

You can optionally specify the module name on the END_MODULE statement; this is particularly useful if you place more than one MODULE declaration in the same HP SDL source file. The module name is case-sensitive and must match exactly (in case) the name specified on the MODULE declaration.

4.2 MODULE Format

A MODULE declaration has the following syntax:


MODULE module-name [ IDENT "ident-string" ]; 
 [ module-body ]; 
     . 
     . 
     . 
END_MODULE [ module-name ]; 

MODULE module-name

Specifies any valid HP SDL identifier you want to use to identify the module.

[IDENT "ident-string"]

Specifies any valid HP SDL identifier, or a string of any characters, that must be enclosed in quotation marks (" ") and that either further identifies the module or is a version number.

[module-body]

Is one or more of the following:

END_MODULE [module-name]

Marks the end of the MODULE declaration. The module-name, if specified, must match the name on the most recently specified MODULE declaration.

ITEM Declaration

The following sections describe the function and format of an ITEM declaration.

4.3 ITEM Description

An ITEM declaration defines scalar items and single-dimensional arrays of scalar items that are not members of aggregates. You must specify an item name and data type on the ITEM declaration. For example:


ITEM block_list_id WORD; 

This declaration specifies the scalar item block_list_id of data type WORD.

4.4 ITEM Format

An ITEM declaration has the following syntax:


ITEM item-name { data-type }           [ COMMON ] 
               { user-type sizeopt }   [ GLOBAL ] 
                                       [ TYPEDEF ] 
 
                                       [ BASEALIGN basealign-option ] 
 
                                       [ DIMENSION [ lbound: ] hbound ] 
 
                                       [ PREFIX prefix-string ] 
 
                                       [ TAG tag-string ]; 

ITEM item-name

Specifies any valid HP SDL name used to identify the item.

data-type

Is any valid HP SDL data type (see Section 3.2.3).

user_type sizeopt

Is a user-defined data type using the DECLARE statement's SIZEOF clause, shown and described in Section 3.10.

[COMMON]

[GLOBAL]

[TYPEDEF]

Is the storage class of the item, if other than the default (based) storage class (see Section 3.2.2.4).

[BASEALIGN basealign-option ]

BASEALIGN specifies the alignment of an ITEM. basealign-option is either an integer expression in parentheses or the name of a data type.

BASEALIGN aligns the item on a multiple of the value of the basealign-option.

[DIMENSION [lbound:]hbound]

Specifies that the item is an array. If a single value is specified, that value indicates the number of elements in the array. Otherwise, lbound and hbound represent lower and upper bounds of the array, respectively (see Section 3.2.2.7).

[PREFIX prefix-string]

Specifies a user-defined prefix that becomes part of the identifier. It can be any valid HP SDL name with 0 to 32 characters, may or may not be enclosed in quotation marks (" "), and may be null (see Section 3.2.2.2).

[TAG tag-string]

Specifies the user-defined tag that follows the prefix used in forming the identifier. It can be any valid HP SDL name with 0 to 32 alphabetic or numeric characters; the tag must be enclosed in quotation marks (" ") if it begins with a numeric character (see Section 3.2.2.2).

AGGREGATE Declaration

The following sections describe the function and format of AGGREGATE and subaggregate declarations.

4.5 AGGREGATE Description

An AGGREGATE declaration defines nonscalar items and dimensional arrays of nonscalar items. An aggregate must contain at least one member declaration. The body of an aggregate can also contain local symbol assignments, CONSTANT declarations, and subaggregate declarations.

You must specify a valid aggregate name on the AGGREGATE declaration. For example:


AGGREGATE dcb STRUCTURE; 
        type CHARACTER; 
        size WORD; 
        next ADDRESS; 
        END dcb; 

You must terminate an AGGREGATE declaration with the END statement. You can optionally specify the aggregate name on the END statement. The aggregate name is case-sensitive and must match exactly (in case) the name specified on the AGGREGATE declaration.

An aggregate that is the target of an ADDRESS declaration must have the default (BASED) storage class.

4.5.1 Subaggregate Declaration

Subaggregates are declared using the keyword STRUCTURE or UNION. Within an aggregate, subaggregates can be nested up to eight levels deep. For example:


AGGREGATE tree_node STRUCTURE; 
 opcode WORD; 
 lang_bits UNION; 
  pli_bits STRUCTURE; 
      resolved BITFIELD; 
      psv BITFIELD; 
      mark1 BITFIELD; 
      spare_bits BITFIELD LENGTH 5; 
      END pli_bits; 
  c_bits STRUCTURE; 
      value_variable_size BITFIELD; 
      psv BITFIELD; 
      expanded BITFIELD; 
      resolved BITFIELD; 
      reduced BITFIELD; 
      spare_bits BITFIELD LENGTH 3; 
      END c_bits; 
  END lang_bits; 
END tree_node; 

In this example, the structures pli_bits and c_bits are both subaggregates of the union lang_bits. Because lang_bits is a union, c_bits and pli_bits occupy the same storage.

The COMMON, GLOBAL, BASED pointer-name, and ORIGIN options are invalid for a subaggregate. All other AGGREGATE options are valid.

4.5.2 STRUCTURE Declaration

STRUCTURE declarations produce aggregate or subaggregate declarations that are structures. The members are not overlaid; each member has a unique offset from the beginning of the structure, which means that members occupy consecutive storage locations.

The following shows the syntax of a first-level STRUCTURE declaration:

AGGREGATE aggregate-name STRUCTURE [ options ]; 

The following shows the syntax of a STRUCTURE declaration as an aggregate member, that is, a subaggregate STRUCTURE declaration:

member-name STRUCTURE [ options ]; 

4.5.3 UNION Declaration

UNION declarations produce aggregate or subaggregate declarations that are unions. The first-level members are overlaid, which means that they occupy the same storage location. Each first-level member begins at the beginning of the union and, thus, has an offset of zero. A UNION declaration lets you represent the same storage location using different names and different data types.

The following shows the syntax of a first-level UNION declaration:

AGGREGATE aggregate-name UNION [ options ]; 

The following shows the syntax of a UNION declaration as an aggregate member, that is, a subaggregate UNION declaration:

member-name UNION [ options ] 

4.5.4 Implicit Union Declarations

You may specify data types on an AGGREGATE declaration to cause the AGGREGATE declaration to become an implicit union declaration. An implicit union declaration has these features:

The following HP SDL source code shows the syntax of an implicit union (structure B defines the implicit union declaration):


AGGREGATE A STRUCTURE; 
    B STRUCTURE LONGWORD; 
        bit_string1 BITFIELD LENGTH 1; 
        bit_string2 BITFIELD LENGTH 4; 
    END B; 
    last_item WORD; 
END A; 

This implicit union declaration would be more cumbersome if represented as shown in the following STRUCTURE subaggregate:


AGGREGATE A STRUCTURE; 
    X UNION ; 
        B LONGWORD; 
        Y STRUCTURE ; 
            bit_string1 BITFIELD LENGTH 1; 
            bit_string2 BITFIELD LENGTH 4; 
        END Y; 
    END X; 
    last_item WORD; 
END A; 

In the previous example, the names X and Y become HP SDL generated "filler" names in the implicit union case.

You do not have to define the union X and the structure Y if an implicit union declaration is used. By giving the structure Y a type, HP SDL creates a union of field Y with the specified type overlaid with a structure containing the fields in Y. In some language translations, such as HP BLISS and HP MACRO, the HP SDL-generated union and structure (X and Y above) can be suppressed in the output because they are considered extraneous fields. In other languages, such as Kednos PL/I and HP C, it is necessary to use the HP SDL-generated union and structure to generate the correct offsets within a structure. Because the union is of the length specified in the structure type, no filler is necessary to ensure that subsequent fields (for example, last_item) are at the correct offset. If the fields of a structure extend past the size specified, HP SDL flags the overflow. The Kednos PL/I translation for the previous implicit union declaration example is as follows:


DCL 1 A  BASED , 
     2 fill_0 union, 
      3 B fixed binary(31), 
      3 fill_1 , 
       4 bit_string1 bit(1), 
       4 bit_string2 bit(4), 
       4 fill_1$$v_fill_2 bit(3), 
     2 last_item fixed binary(15); 

The HP SDL source file EXAMPLE.SDL in SDL$EXAMPLES shows an example of an implicit union declaration.

4.5.5 Implicit Union Declarations with the Optional DIMENSION Keyword

The following is an example of a HP SDL structure defined with a data type and the DIMENSION keyword:


AGGREGATE fid STRUCTURE WORD DIMENSION 3; 
    first WORD; 
    second WORD; 
    third WORD; 
END fid; 

In the previous example, a single structure is overlaid by an array of elements of the type specified by the structure type.

The fid structure is a three-word field that can be addressed as a single field or by each individual word so that it is easily defined in HP SDL as represented above. The following is the Kednos PL/I translation for the HP SDL source code in the previous example:


DCL 1 fill_0 union BASED , 
     2 fid (1:3) fixed binary(15), 
     2 fill_1 , 
      3 first fixed binary(15), 
      3 second fixed binary(15); 
      3 third fixed binary(15); 

The implicit union declaration allows structures to grow without the need to modify any trailing fillers. HP SDL detects any overflow that may occur if the structure grows past the size of its data type. The size of the aggregate (in bytes) is equal to the size of the data type (in bytes) multiplied by the upper dimension (if any). If the size of the aggregate is greater than the sum of the size of all its members, HP SDL still translates the declaration. However, if the size of the members exceeds the size of the aggregate, HP SDL issues a message that has the following format:

%SDL-E-TOOMANYFIELDS, Structure fill_0 has too many fields [Line ?] 

In the previous example, fill_0 is the HP SDL-generated name for the first union aggregate.

4.5.6 Forcing Negative Offsets

The default origin of an aggregate is the beginning of the first aggregate member. You may specify the ORIGIN option on a level-1 AGGREGATE declaration to indicate that the origin is located at the beginning of any aggregate member. The resulting declaration forces all aggregate members declared before the specified origin to be located at negative offsets from the origin. For example:


 AGGREGATE nodes STRUCTURE ORIGIN qflink; 
  flink ADDRESS; 
  blink ADDRESS; 
  qflink ADDRESS; 
  qblink ADDRESS; 
  END; 

This declaration defines the origin of the structure nodes to be at the member qflink, so you may address flink and blink as negative offsets from qflink. Specifying an origin does not change the values of the current bit and byte offset symbols (^ and :). These are always calculated as being relative to the beginning of the aggregate.

4.5.7 Forcing Data Alignment

HP SDL forces all AGGREGATE and subaggregate declarations to begin on byte boundaries. Thus, if an aggregate or subaggregate ends with BITFIELD declarations that do not end on byte boundaries, HP SDL ensures that the next aggregate begins on a byte boundary by supplying BITFIELD declarations as fillers, if necessary.

When HP SDL adds BITFIELD declarations, it determines the length required and provides a unique name of the form string$V_FILL_n. The string is the prefix supplied in the AGGREGATE declaration, or the aggregate name if no prefix was supplied. Within an aggregate, n begins at 0 and is incremented for each filler required.

The subaggregate declarations shown in the following example declare filler bitfields to force byte alignment at the end of each subaggregate; this programming practice makes it unnecessary for HP SDL to perform the alignment.


AGGREGATE tree_node STRUCTURE; 
 opcode WORD; 
 lang_bits UNION; 
  pli_bits STRUCTURE; 
      resolved BITFIELD; 
      psv BITFIELD; 
      mark1 BITFIELD; 
      spare_bits BITFIELD LENGTH 5; 
      END pli_bits; 
  c_bits STRUCTURE; 
      value_variable_size BITFIELD; 
      psv BITFIELD; 
      expanded BITFIELD; 
      resolved BITFIELD; 
      reduced BITFIELD; 
      spare_bits BITFIELD LENGTH 3; 
      END c_bits; 
  END lang_bits; 
END tree_node; 

The current bit offset is set at 0 at the beginning of each aggregate and is incremented by the bit lengths of each structure member in the aggregate at that level. In the following example, HP SDL forces the structure flags to be aligned on a byte boundary.


AGGREGATE dcb STRUCTURE PREFIX dcb$; 
 . 
 . 
 . 
 uflags STRUCTURE; 
  context BITFIELD LENGTH 3; 
  local BITFIELD; 
  END uflags; 
 flags STRUCTURE; 
  extern BITFIELD; 
  relo BITFIELD; 
  END flags; 

The Kednos PL/I translation of the HP SDL AGGREGATE declaration in the previous example is as follows:


%replace dcb$s_dcb by 2; 
dcl 1 dcb  based, 
     2 dcb$r_uflags , 
      3 dcb$v_context bit(3), 
      3 dcb$v_local bit(1), 
      3 dcb$v_fill_0 bit(4), 
     2 dcb$r_flags , 
      3 dcb$v_extern bit(1), 
      3 dcb$v_relo bit(1), 
      3 dcb$v_fill_1 bit(6); 

The bit offsets of the members of the structures in the previous HP SDL example are shown in the following table.
Member Bit Offset
dcb$v_context 0
dcb$v_local 3
dcb$v_fill_0 4
dcb$v_extern 0
dcb$v_relo 1
dcb$v_fill_1 2

4.5.8 Using Offset Symbols

The period (.) represents the current byte offset from the origin in an AGGREGATE declaration. If the ORIGIN option is specified, the value of the period is equal to the byte offset from the member specified using the ORIGIN option. The current byte offset is useful for capturing the size of an aggregate or a portion of it. For example, in the declaration of a variable-length data structure, you can capture the size of the fixed-length portion.

The colon (:) represents the current byte offset relative to the first member in an AGGREGATE declaration. The value is not affected by the presence of an ORIGIN option.

The circumflex (^) represents the current bit offset relative to the most recently declared aggregate or byte-aligned element.

The following example shows the use of the byte offset symbols.


AGGREGATE operator STRUCTURE PREFIX opr_; 
   flink ADDRESS; 
   blink ADDRESS; 
   opcount WORD; 
   optype CHARACTER LENGTH 1; 
   id WORD; 
   flags STRUCTURE; 
       is_constant_size BITFIELD LENGTH 1; 
       is_terminator BITFIELD LENGTH 1; 
       context BITFIELD LENGTH 3; 
       filler BITFIELD LENGTH 8-^; 
       END; 
   #opsize = .; 
   operands LONGWORD DIMENSION(#max_args); 
   #instruction_size = :; 
   END; 
 
CONSTANT node_size EQUALS #opsize / 2; 
CONSTANT inst_size EQUALS #instruction_size; 

In the previous example, the local symbol #opsize captures the byte offset following the fixed-length portion of the structure operator. This value is subsequently used in the CONSTANT declaration, which defines the size of the constant portion of the structure in words.

The flags structure is byte aligned by the field filler, which makes use of the current bit offset symbol to compute the size of this field.

The CONSTANT inst_size defines the size of the entire structure.

4.6 AGGREGATE Format

An AGGREGATE declaration has the following syntax:


AGGREGATE aggregate-name    { STRUCTURE }   [ data-type ] 
                            { UNION     } 
 
                  [ COMMON ] 
                  [ GLOBAL ] 
                  [ TYPEDEF ] 
                  [ BASED pointer-name ] 
 
                  [ ALIGN ] 
                  [ NOALIGN ] 
                  [ BASEALIGN basealign-option ] 
 
                  [ DIMENSION [ lbound: ] hbound ] 
 
                  [ MARKER marker-string ] 
 
                  [ PREFIX prefix-string ] 
 
                  [ TAG tag-string ] 
 
                  [ ORIGIN member-name ] 
 
                  [ FILL ]; 
aggregate-body 
   . 
   . 
   . 
END [ aggregate-name ]; 

AGGREGATE aggregate-name

Specifies any valid HP SDL name used to identify the aggregate.

{STRUCTURE}

{UNION}

Is the type of aggregate (see Section 4.5).

[data-type]

If specified, causes the AGGREGATE declaration to become an implicit union declaration (see Section 4.5).

[COMMON]

[GLOBAL]

[BASED pointer-name]

[TYPEDEF]

Is the storage class of the aggregate, if other than the default (BASED) (see Section 3.2.2.4). If an aggregate is the object of an ADDRESS declaration, it must have either the default or the BASED pointer-name storage class.

[ALIGN]

[NOALIGN]

[BASEALIGN basealign-option]

The ALIGN and NOALIGN keywords can be used to align (or de-align) the members of an aggregate on their natural boundary. The BASEALIGN keyword ensures that the size of an aggregate is a multiple of the given alignment. The BASEALIGN keyword therefore takes an argument, which specifies the alignment, either an expression in parenthesis or the name of a data type.

For example:


AGGREGATE MyStruct STRUCTURE ALIGN; 
This aligns every member in the structure.


AGGREGATE MyStruct STRUCTURE NOALIGN; 
No action will be taken to ensure that the members of the aggregate will be aligned.


AGGREGATE MyStruct STRUCTURE BASEALIGN (8); 
The aggregate will be padded, so that in an array of elements of this aggregate, all elements will have a size that is a multiple of the given alignment (256, 28 ).

Alignment attributes on aggregates can be partially overridden by specifying alignment attributes on the members of the aggregate.

See also Section 3.2.2.3.

[DIMENSION [lbound:]hbound]

Specifies that the aggregate is an array. If a single value is specified, that value indicates the number of elements in the array. Otherwise, lbound and hbound represent lower and upper bounds of the array, respectively.

[MARKER marker-string]

Specifies the prefix used to form the aggregate name. It may be any valid HP SDL name with 0 to 32 characters, may or may not be enclosed in quotation marks (" "), and may be null.

[PREFIX prefix-string]

Specifies the prefix used in forming the names of aggregate members. It may be any valid HP SDL name with 0 to 32 characters, may or may not be enclosed in quotation marks (" "), and may be null (see Section 3.2.2.2).

[TAG tag-string]

Specifies the tag used to form the aggregate name. The tag is appended to the prefix, if a prefix was specified. It can have 0 to 32 alphabetic or numeric characters; the tag must be enclosed in quotation marks (" ") if it begins with a numeric character (see Section 3.2.2.2).

[ORIGIN member-name]

Specifies the name of a member of this aggregate that is to be used as the origin of the aggregate.

Member declarations produce declarations of the members of an aggregate and have the following syntax:


member-name { data-type }            [ ALIGN ] 
            { aggregate-name }       [ NOALIGN ] 
            { user-type sizeopt }    [ BASEALIGN basealign-option ] 
 
                                     [ DIMENSION [ lbound: ] hbound ] 
                                     [ PREFIX prefix-string ] 
                                     [ TAG tag-string ] 
 
                                     [ FILL ]; 

member-name

Is any valid HP SDL name used to identify the member.

{data-type}

Is any valid HP SDL data type (see Section 3.2.3).

{aggregate-name}

Is the name of the previously declared aggregate to be used as a type name. The name must be the full (HP SDL-expanded) aggregate name, including the prefix and tag.

{user-type sizeopt}

Is a user-defined variable using the DECLARE statement's SIZEOF clause, shown and described in Section 3.10.

[ALIGN]

[NOALIGN]

[BASEALIGN basealign-option]

Alignment attributes on a structure can be overridden with alignment attributes on a member declaration. For example:


Previous Next Contents Index