Introduction | Projects and Files | Statements | Expressions | Symbols | Types |
Attributes | Labels | Non-Member Functions | Constructing Declarations | Example Programs | Index |
Sage++'s type classes correspond to the type structures of the languages Sage++ can deal with. Types characterize the properties of symbols. Because C++ and Fortran 90 have fairly rich type structures, there are many Sage++ type classes.
All Languages:
C:
C++:
pC++
SgType
is the base class for all classes that represent types.
As with symbols, types in a file form a list that can be accessed with the
function SgFile::firstType()
. The next()
function returns
the type node following this
. The function copy()
returns a
copy of the type node. Many types are defined in terms of other types.
For example, an array type has a base type that may be a pointer type
which has a base type that may be an integer or a class, etc.
The baseType()
function always access the next type in the chain.
For the language pC++ there is a dummy type called ElementType
which is used as a ``place holder'' or parameter for a type that is
supplied later. Another function equivalentToType()
can be used
to test to types to see if they are equivalent. Please
see section Building Variable and Parameter Declarations for more information
about types in Sage++.
class SgType { public: PTR_TYPE thetype; SgType(int variant); SgType(int var, SgExpression *len,SgType *base); SgType(int var, SgSymbol *symb); SgType(int var, SgSymbol *firstfield, SgStatement *structstmt); inline SgType(PTR_TYPE type); inline SgType(SgType &); inline int variant(); inline int id(); inline SgSymbol *symbol(); inline SgType ©(); inline SgType *copyPtr(); inline SgType *next(); inline int isTheElementType(); inline int equivalentToType(SgType &type); inline int equivalentToType(SgType *type); inline SgType *internalBaseType(); inline int hasBaseType(); inline SgType *baseType(); inline SgExpression *length();/* This code by Andrew Mauer (ajm) */ /* maskDescriptors:
This routine strips many descriptive type traits which you are probably not interested in cloning for variable declarations, etc.
Returns the getTrueType of the base type being described IF there are no descriptors which are not masked out. The following masks can be specified as an optional second argument: MASK_NO_DESCRIPTORS: Do not mask out anything. MASK_MOST_DESCRIPTORS: Only leave in: signed, unsigned, short, long, const, volatile. MASK_ALL_DESCRIPTORS: Mask out everything.
If you build your own mask, you should make sure that the traits you want to set out have their bits UN-set, and the rest should have their bits set. The complementation (~) operator is a good one to use.
See libSage++.h, where the MASK_*_DESCRIPTORS variables are defined. */
SgType *maskDescriptors (int mask);
/* This code by Andrew Mauer (ajm) */ /* getTrueType:
Since Sage stores dereferenced pointers as PTR(-1) -> PTR(1) -> BASE_TYPE, we may need to follow the chain of dereferencing to find the type which we expect.
This code currently assumes that: o If you follow the dereferencing pointer (PTR(-1)), you find another pointer type or an array type.
We do NOT assume that the following situation cannot occur: PTR(-1) -> PTR(-1) -> PTR(1) -> PTR(1) -> PTR(-1) -> PTR(1)
This means there may be more pointers to follow after we come to an initial "equilibrium".
ALGORITHM:
T_POINTER: [WARNING: No consideration is given to pointers with attributes (ls_flags) set. For instance, a const pointer is treated the same as any other pointer.] 1. Return the same type we got if it is not a pointer type or the pointer is not a dereferencing pointer type.
2. Repeat { get next pointer , add its indirection to current total } until the current total is 0. We have reached an equilibrium, so the next type will not necessarily be a pointer type.
3. Check the next type for further indirection with another call to getTrueType.
T_DESCRIPT: Returns the result of maskDescriptors called with the given type and mask.
T_ARRAY: If the array has zero dimensions, we pass over it. This type arose for me in the following situation: double x[2]; x[1] = 0; T_DERIVED_TYPE: If we have been told to follow typedefs, get the type of the symbol from which this type is derived from, and continue digging. Otherwise return this type.
HITCHES: Some programs may dereference a T_ARRAY as a pointer, so we need to be prepared to deal with that. */
SgType *getTrueType (int mask = MASK_MOST_DESCRIPTORS, int follow_typedefs = 0);
int numberOfAttributes(); int numberOfAttributes(int type); // of a specified type; void *attributeValue(int i); int attributeType(int i); void *attributeValue(int i,int type); // only considering one type attribute void *deleteAttribute(int i); void addAttribute(int type, void *a, int size); // void * can be NULL; void addAttribute(int type); //void * is NULL; void addAttribute(void *a, int size); //no type specifed; void addAttribute(SgAttribute *att); SgAttribute *getAttribute(int i); SgAttribute *getAttribute(int i,int type); };
int equivalentToType
(SgType &type)
SgType *getTrueType
(int mask = MASK_MOST_DESCRIPTORS, int follow_typedefs = 0)
To illustrate the use of the type table, consider the simple problem of identifying when a variable in a variable reference expression is of a given user defined class. More specifically, given
class myClass; myClass x, y; y = x + 2;
then if e
is the expression representing the variable reference to
x
, we would like a function isVarRefOfClass
(i.e., "myClass")
that will return 1
because the class type matches. To do this we
first check to see if e
is indeed a variable reference.
Then, extracting the type of the symbol we should find a derived type.
From the derived type we can find the name of the class.
int isVarRefOfClass(SgExpression *e, char *classname){ SgSymbol *s; SgDerivedType *d; SgClassSymb *cl; SgVarRefExp *exp; if((exp = isSgVarRefExp(e)) == NULL) return 0; s = exp->symbol(); if((d = isSgDerivedType(s->type())) == NULL) return 0; if(cl = isSgClassSymb(d->typeName())) if(!strcmp(cl->identifier(), classname)) return 1; return 0; }
A function of the type
SgSUBCLASS * isSgSUBCLASS( SgBASECLASS *)
is provided for each subclass of SgStatement, SgExpression and SgType. We feel that this mechanism is an effective way to use the strong typing of C++ to reduce errors.
SgType
is used in the following example programs:
Represents types for arrays, for all languages. The parser gives each array variable its own Array type descriptor object.
class SgArrayType: public SgType { // A new array type is generated for each array. // variant == T_ARRAY public: inline SgArrayType(SgType &base_type); inline int dimension(); inline SgExpression *sizeInDim(int i); inline void addDimension(SgExpression *e); inline SgExpression * getDimList(); inline SgType * baseType(); inline void setBaseType(SgType &bt); inline void addRange(SgExpression &e); inline ~SgArrayType(); };
SgArrayType
(SgType &base_type)
SgExpression *sizeInDim
(int i)
void addRange
(SgExpression &e)
SgArrayType
is used in the following example programs:
Represents the following types:
struct
, union
, enum
class
collection
record
class SgClassType: public SgType { // a C struct or Fortran Record, a C++ class, a C Union and a // (note: C Enum no enums!) // and a pC++ collection. note: derived classes are another type. // this type is very simple. it only contains the standard type // info from SgType and a pointer to the class declaration stmt // and a pointer to the symbol that is the first field in the struct. // variant == T_STRUCT, /*T_ENUM,*/ T_CLASS, T_UNION, T_COLLECTION public: // why is struct_decl needed. No appropriate field found. // assumes that first_field has been declared as // FIELD_NAME and the remaining fields have been stringed to it. /* SgClassType(int variant, char *name, SgStatement &struct_decl, int num_fields, SgSymbol &first_field); //this constructor not implemented BW */ SgClassType(int variant, SgStatement &struct_decl, SgSymbol &first_field); SgClassType(int variant, SgStatement &struct_decl); inline SgStatement *structureDecl(); inline SgSymbol *firstFieldSymb(); SgSymbol *fieldSymb(int i); //i = 0,1,2, ... inline ~SgClassType(); int numberOfFields(); };
SgClassType
(int variant, char *name, SgStatement &struct_decl, int num_fields, SgSymbol &first_field)
i
th field.
SgSymbol *field(int i)
method for useful information.
Represents types for functions, for all languages. The important information here is the type of the returned value.
class SgFunctionType: public SgType { // Function Types have a returned value type // variant == T_FUNCTION public: SgFunctionType(SgType &return_val_type); SgType *returnedValue(); void changeReturnedValue(SgType &rv); ~SgFunctionType(); };
SgFunctionType
(SgType &return_val_type)
void changeReturnedValue
(SgType &rv)
Represents the following types:
unsigned
, signed
, long
, short
, extern
, static
, register
private
, virtual
, inline
, volatile
, const
, auto
, friend
syn
, shared
, future
, global
friend
, extern
,
static
, and inline
decl-specifications were handled using SgDescriptType. Starting with
version 1.9 they are modifiers of SgStatement nodes (see the section
on SgStatement for more information).
class SgDescriptType: public SgType { // for example in C: long volatile int x; // long and volatile are modifiers and there is a descriptor // type whose base type is the real type of x. // the modifier is an integer with bits set if the modifier // holds. // the bits are: // BIT_SYN, BIT_SHARED, BIT_PRIVATE, BIT_FUTURE, BIT_VIRTUAL,// BIT_UNSIGNED, BIT_SIGNED, BIT_LONG, BIT_SHORT, // BIT_VOLATILE, BIT_CONST, BIT_TYPEDEF, BIT_AUTO, // BIT_REGISTER, BIT_GLOBAL, and more. // // variant = T_DESCRIPT public: inline SgDescriptType(SgType &base_type, int bit_flag); inline int modifierFlag(); inline void setModifierFlag(int flag); inline ~SgDescriptType(); };
SgDescriptType
(SgType &base_type, int bit_flag)
void setModifierFlag
(int flag)
SgDescriptType
is used in the following example programs:
Represents C pointer type. The important information is encoded in the base type, i.e. the type of thing this pointer can point to.
class SgPointerType: public SgType { // A pointer type contains only one hany bit of information: // the base type. // can also have a modifier like BIT_CONST BIT_GLOBAL. see SgDescriptType. // variant == T_POINTER public: SgPointerType(SgType &base_type); SgPointerType(SgType *base_type); inline SgType *baseType(); inline int indirection(); inline void setIndirection(int); inline int modifierFlag(); inline void setModifierFlag(int flag); inline void setBaseType(SgType &baseType); inline ~SgPointerType(); };
SgPointerType
(SgType &base_type)
SgPointerType
(SgType *base_type)
const
) that refer
to pointer types (e.g., int *const;
)
inline void setModifierFlag
(int flag)
const
) that refer to
pointer types (for example: int * const:
)
void setBaseType
(SgType &baseType)
SgPointerType
is used in the following example programs:
This type is used to represent types of variables that have user-defined
types in C++. Those can be defined using typedef
or class
.
For example, given a declaration:
class A a;
the type of the symbol corresponding to a
is SgDerivedType whose
typeName points to the symbol corresponding to A
. Note that the
type of A
is not SgDerivedType but rather SgClassType.
class SgDerivedType: public SgType { // for example: typedef int integer; go to the symbol table // for the base type and Id. // variant == T_DERIVED_TYPE public: inline SgDerivedType(SgSymbol &type_name); inline SgSymbol * typeName(); inline ~SgDerivedType(); };
SgDerivedType
(SgSymbol &type_name)
SgDerivedType
is used in the following example programs:
Represents C++ reference types.
class SgReferenceType: public SgType { // A reference (&xx in c+=) type contains only one hany bit of information: // the base type. // variant == T_REFERENCE public: inline SgReferenceType(SgType &base_type); inline SgType *baseType(); inline void setBaseType(SgType &baseType); inline ~SgReferenceType(); inline int modifierFlag(); inline void setModifierFlag(int flag); };
SgReferenceType
(SgType &base_type)
void setBaseType
(SgType &baseType)
SgReferenceType
is used in the following example programs:
It appears that this class is presently not used for anything.
class SgDerivedClassType: public SgType { // for example: typedef int integer; go to the symbol table // for the base type and Id. // variant == T_DERIVED_TYPE public: inline SgDerivedType(SgSymbol &type_name); inline SgSymbol * typeName(); inline ~SgDerivedType(); };
SgDerivedClassType
(SgSymbol &type_name)
Represents pC++ collection classes.
class SgDerivedCollectionType: public SgType { // for example: // Collection DistributedArray {body1} ; // class object {body2} ; // DistributedArray<object> X; // X is of type with variant = T_DERIVED_COLLECTION public: inline SgDerivedCollectionType(SgSymbol &s, SgType &t); inline SgType *elementClass(); inline void setElementClass(SgType &ty); inline SgSymbol *collectionName(); inline SgStatement *createCollectionWithElemType(); inline ~SgDerivedCollectionType(); };
SgDerivedCollectionType
(SgSymbol &s, SgType &t)
t
is the collection type.
void setElementClass
(SgType &ty)
SgStatement *createCollectionWithElemType
()
SgDerivedCollectionType
is used in the following example programs: