![]() |
![]() |
![]() |
General Information
Tutorials
Reference Manuals
Libraries
Translation Tasks
Tools
Administration
![]() |
![]() |
Tutorial on Type AnalysisPointer Types
In this section we introduce pointer types to our language.
A type denoted
Two new The following concrete productions are added: Pointer.con[48]== TypeDenoter: PointerType. PointerType: TypeDenoter '!'. Variable: Variable '!'. Variable: Variable '&'. This macro is attached to a product file. Here is an example program that uses these pointer constructs in different contexts: PointerExamp[49]== begin var int k; var int! pi, int! pj; var record int i, bool b, real! r end! rv; type record int x, t! next end t; var t l; pi = k&; pi! = 1; pi = pj; pi! = pj!; rv!.b = true; rv!.r! = 3.2; l.next!.x = 1; end This macro is attached to a product file.
The property Pointer.pdl[50]== PointsTo: DefTableKey [KReset]; This macro is attached to a product file.
Types
As discussed in the section where we introduced record types,
we specify a PointerType.lido[51]== SYMBOL PointerType INHERITS TypeDenotation END; RULE: TypeDenoter ::= PointerType COMPUTE TypeDenoter.Type = PointerType.Type; END; RULE: PointerType ::= TypeDenoter '!' COMPUTE PointerType.GotType = ResetTypeName (KResetPointsTo (PointerType.Type, TypeDenoter.Type), "pointer..."); IF (RecursivePtrType (PointerType.Type, PointerType.Type), message (ERROR, "recursive pointer type", 0, COORDREF)) <- INCLUDING Program.GotType; END; This macro is attached to a product file. The last computation checks that the pointer type denoted here does not refer to itself via pointer relations only. Note: Although a message is given in such erroneous cases, functions that operate on types must be coded such that they can deal with such types.
We now state how pointer types are checked for equivalence.
Our language requires that two pointer type notations shall
be considered to be equal types if the types they point to
are equal. Such cases where different type keys may represent
equal types are not yet captured by the initial frame of the
Here, the following Pointer.EqualTypes.phi[52]== { /* pointer types: */ DefTableKey tr1, tr2; tr1 = TransDefer (GetPointsTo (t1, NoKey)); if (tr1 != NoKey) { /* tr1 is a pointer type: */ tr2 = TransDefer (GetPointsTo (t2, NoKey)); if (tr2 == NoKey) return 0; /* tr2 is not a pointer type */ if (RecursivePtrType (tr1, tr1) || RecursivePtrType (tr2, tr2)) return 0; /* recursive pointer type */ return EqualTypes (tr1, tr2); } }/* end pointer types */ This macro is attached to a product file.
The Pointer.TypeFct.phi[53]== #ifdef PROTO_OK int RecursivePtrType (DefTableKey orig, DefTableKey chk) #else int RecursivePtrType (orig, chk) DefTableKey orig, chk; #endif /* 1 is returned if the type chk directly or indirectly points to orig; 0 is returned otherwise. */ { chk = TransDefer (GetPointsTo (chk, NoKey)); if (chk == NoKey) return 0; if (chk == orig) return 1; return RecursivePtrType (orig, chk); } This macro is attached to a product file. Pointer.TypeFctHdr.phi[54]== extern int RecursivePtrType ELI_ARG((DefTableKey orig, DefTableKey chk)); This macro is attached to a product file.
For the contents operation applied to a PointerVar.lido[55]== RULE: Variable ::= Variable '!' COMPUTE Variable[1].Type = TransDefer (GetPointsTo (Variable[2].Type, NoKey)); IF (EQ (Variable[1].Type, NoKey), message (ERROR, "is not a pointer variable", 0, COORDREF)); END; This macro is attached to a product file.
The address operator implicitly creates a pointer type
that AddressVar.lido[56]== RULE: Variable ::= Variable '&' COMPUTE Variable[1].Type = KResetPointsTo (KResetTypeName (KResetIsType (NewKey (), 1), "addr of ..."), Variable[2].Type); END; This macro is attached to a product file.
|