Update copyright to LGPL on all files
[dyninst.git] / symtabAPI / h / Type.h
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31                              
32 #ifndef __Type_h__
33 #define __Type_h__
34
35 #include "Serialization.h"
36 #include "Annotatable.h"
37 #include "symutil.h"
38
39 namespace Dyninst{
40 namespace SymtabAPI{
41
42 class Module;
43 class Symtab;
44 class Symbol;
45 class Type;
46 class typeEnum;
47 class typePointer;
48 class typeFunction;
49 class typeSubrange;
50 class typeArray;
51 class typeStruct;
52 class typeUnion;
53 class typeScalar;
54 class typeCommon;
55 class typeTypedef;
56 class typeRef;
57 class CBlock;
58 class typeCollection;
59 class fieldListType;
60 class TypeMemManager;
61
62 //TODO?? class BPatch(to be  ??)function;
63
64
65 typedef enum {dataEnum,
66               dataPointer,
67               dataFunction,
68               dataSubrange,
69               dataArray,
70               dataStructure,
71               dataUnion,
72               dataCommon,
73               dataScalar,
74               dataTypedef,
75               dataReference,
76               dataUnknownType,
77               dataNullType,
78               dataTypeClass
79 } dataClass;
80
81 SYMTAB_EXPORT const char *dataClass2Str(dataClass dc);
82
83 typedef int typeId_t;
84
85 typedef enum {
86    visPrivate, 
87    visProtected, 
88    visPublic,
89    visUnknown
90 } visibility_t;
91
92 /*
93  * visibility: Accessibility of member data and functions
94  * These values follow the 'fieldname:' after the '/' identifier.
95  * visPrivate   == 0 gnu Sun -- private
96  * visProtected == 1 gnu Sun -- protected
97  * visPublic    == 2 gnu Sun -- public
98  * visUnknown visibility not known or doesn't apply(ANSIC), the default
99  *
100  */
101  
102 SYMTAB_EXPORT const char *visibility2Str(visibility_t v);
103
104 #define FIELD_ANNOTATABLE_CLASS AnnotatableDense
105
106 class Field : public Serializable, public FIELD_ANNOTATABLE_CLASS 
107 {
108    friend class typeStruct;
109    friend class typeUnion;
110    friend class typeCommon;
111    friend class CBlock;
112    
113    std::string fieldName_;
114    Type *type_;
115    visibility_t  vis_;
116    int offset_;
117
118    /* Method vars */
119  protected:
120    void copy(Field &);
121
122  public:
123    SYMTAB_EXPORT Field(); 
124    SYMTAB_EXPORT Field(std::string name, Type *typ, int offsetVal = -1, 
125                    visibility_t vis = visUnknown);
126    
127    // Copy constructor
128    SYMTAB_EXPORT Field(Field &f);
129    SYMTAB_EXPORT ~Field();
130
131    SYMTAB_EXPORT std::string &getName();
132    SYMTAB_EXPORT Type *getType();
133    SYMTAB_EXPORT visibility_t getVisibility();
134    SYMTAB_EXPORT unsigned int getSize();
135    SYMTAB_EXPORT int getOffset();
136    
137    SYMTAB_EXPORT void fixupUnknown(Module *);
138    SYMTAB_EXPORT Serializable * serialize_impl(SerializerBase *sb, 
139                    const char *tag="Field") THROW_SPEC(SerializerError);
140    SYMTAB_EXPORT virtual bool operator==(const Field &) const;
141 };
142                                   
143 #define TYPE_ANNOTATABLE_CLASS AnnotatableDense
144
145 class Type : public Serializable, public  TYPE_ANNOTATABLE_CLASS 
146 {
147    friend class typeCollection;
148    friend std::string parseStabString(Module *, int linenum, char *, int, 
149                                       typeCommon *);
150    static Type* upgradePlaceholder(Type *placeholder, Type *new_type);
151
152    public:
153
154    SYMTAB_EXPORT virtual void serialize_specific(SerializerBase *) 
155            THROW_SPEC(SerializerError) {}
156
157    SYMTAB_EXPORT Serializable * serialize_impl(SerializerBase *, 
158                    const char * = "Type") THROW_SPEC (SerializerError);
159
160  protected:
161    typeId_t ID_;           /* unique ID of type */
162    std::string name_;
163    unsigned int  size_;    /* size of type */
164    dataClass   type_;
165    
166    /**
167     * We set updatingSize to true when we're in the process of
168     * calculating the size of container structures.  This helps avoid
169     * infinite recursion for self referencial types.  Getting a
170     * self-referencial type probably signifies an error in another
171     * part of the type processing code (or an error in the binary).
172     **/
173    bool updatingSize;
174    
175    static typeId_t USER_TYPE_ID;
176
177    // INTERNAL DATA MEMBERS
178    unsigned int refCount;
179
180 protected:
181    SYMTAB_EXPORT virtual void updateSize() {}
182
183    SYMTAB_EXPORT virtual void merge( Type * /* other */ ) { }
184
185 public:
186    SYMTAB_EXPORT virtual bool operator==(const Type &) const;
187    SYMTAB_EXPORT virtual bool isCompatible(Type *oType);
188    SYMTAB_EXPORT virtual void fixupUnknowns(Module *);
189
190    SYMTAB_EXPORT Type(std::string name, typeId_t ID, dataClass dataTyp = dataNullType);
191    SYMTAB_EXPORT Type(std::string name, dataClass dataTyp = dataNullType);
192
193    SYMTAB_EXPORT Type();
194    SYMTAB_EXPORT virtual ~Type();
195
196    // A few convenience functions
197    SYMTAB_EXPORT static Type *createFake(std::string name);
198    /* Placeholder for real type, to be filled in later */
199    SYMTAB_EXPORT static Type *createPlaceholder(typeId_t ID, std::string name = "");
200    
201    SYMTAB_EXPORT typeId_t getID() const;
202    SYMTAB_EXPORT unsigned int getSize();
203    SYMTAB_EXPORT bool setSize(unsigned int size);
204    SYMTAB_EXPORT std::string &getName();
205    SYMTAB_EXPORT bool setName(std::string);
206    SYMTAB_EXPORT dataClass getDataClass() const;
207
208    // INTERNAL METHODS
209    SYMTAB_EXPORT void incrRefCount();
210    SYMTAB_EXPORT void decrRefCount(); 
211    //Methods to dynamically cast generic Type Object to specific types.
212    
213    SYMTAB_EXPORT typeEnum *getEnumType();
214    SYMTAB_EXPORT typePointer *getPointerType();
215    SYMTAB_EXPORT typeFunction *getFunctionType();
216    SYMTAB_EXPORT typeSubrange *getSubrangeType();
217    SYMTAB_EXPORT typeArray *getArrayType();
218    SYMTAB_EXPORT typeStruct *getStructType();
219    SYMTAB_EXPORT typeUnion *getUnionType();
220    SYMTAB_EXPORT typeScalar *getScalarType();
221    SYMTAB_EXPORT typeCommon *getCommonType();
222    SYMTAB_EXPORT typeTypedef *getTypedefType();
223    SYMTAB_EXPORT typeRef *getRefType();
224    SYMTAB_EXPORT std::string specificType();
225 };
226
227 // Interfaces to be implemented by intermediate subtypes
228 // We have to do this thanks to reference types and C++'s lovely 
229 // multiple inheritance
230
231 class fieldListInterface {
232  public:
233    SYMTAB_EXPORT virtual ~fieldListInterface() {};
234    SYMTAB_EXPORT virtual std::vector<Field *> *getComponents() const = 0;
235 };
236
237 class rangedInterface {
238  public:
239    SYMTAB_EXPORT virtual ~rangedInterface() {};
240    SYMTAB_EXPORT virtual long getLow() const = 0;
241    SYMTAB_EXPORT virtual long getHigh() const  = 0;
242 };  
243
244 class derivedInterface{
245  public:
246    SYMTAB_EXPORT virtual ~derivedInterface() {};
247    SYMTAB_EXPORT virtual Type *getConstituentType() const = 0;
248 };
249
250 // Intermediate types (interfaces + Type)
251
252 class fieldListType : public Type, public fieldListInterface 
253 {
254  private:
255    void fixupComponents();
256  protected:
257    std::vector<Field *> fieldList;
258    std::vector<Field *> *derivedFieldList;
259    SYMTAB_EXPORT fieldListType(std::string &name, typeId_t ID, dataClass typeDes);
260    /* Each subclass may need to update its size after adding a field */
261  public:
262    SYMTAB_EXPORT fieldListType();
263    SYMTAB_EXPORT ~fieldListType();
264    SYMTAB_EXPORT bool operator==(const Type &) const;
265    SYMTAB_EXPORT std::vector<Field *> *getComponents() const;
266    
267    SYMTAB_EXPORT std::vector<Field *> *getFields() const;
268    
269    SYMTAB_EXPORT virtual void postFieldInsert(int nsize) = 0;
270    
271    /* Add field for C++ struct or union */
272    SYMTAB_EXPORT void addField(std::string fieldname, Type *type, int offsetVal = -1, visibility_t vis = visUnknown);
273    SYMTAB_EXPORT void addField(unsigned num, std::string fieldname, Type *type, int offsetVal = -1, visibility_t vis = visUnknown);
274    SYMTAB_EXPORT void addField(Field *fld);
275    SYMTAB_EXPORT void addField(unsigned num, Field *fld);
276   
277    SYMTAB_EXPORT void serialize_fieldlist(Dyninst::SerializerBase *, 
278                    const char * = "fieldListType") THROW_SPEC (SerializerError);
279   // void addField(const std::string &fieldname,  dataClass typeDes, 
280   //               Type *type, int offset, int size, visibility_t vis = visUnknown);
281 };
282
283 class rangedType : public Type, public rangedInterface {
284  protected:
285    long low_;
286    long hi_;
287    //char *low;
288    //char *hi;
289  protected:
290    //rangedType(const std::string &name, typeId_t ID, dataClass typeDes, int size, const char *low, const char *hi); 
291    SYMTAB_EXPORT rangedType(std::string &name, typeId_t ID, dataClass typeDes, int size, long low, long hi);
292    SYMTAB_EXPORT rangedType(std::string &name, dataClass typeDes, int size, long low, long hi);
293    SYMTAB_EXPORT void serialize_ranged(SerializerBase *, 
294                    const char * = "rangedType") THROW_SPEC (SerializerError);
295  public:
296    SYMTAB_EXPORT rangedType();
297    SYMTAB_EXPORT ~rangedType();
298    SYMTAB_EXPORT bool operator==(const Type &) const;
299    SYMTAB_EXPORT long getLow() const { return low_; }
300    SYMTAB_EXPORT long getHigh() const { return hi_; }
301 };
302
303 class derivedType : public Type, public derivedInterface {
304  protected:
305    Type *baseType_;
306  protected:
307    SYMTAB_EXPORT derivedType(std::string &name, typeId_t id, int size, dataClass typeDes);
308    SYMTAB_EXPORT derivedType(std::string &name, int size, dataClass typeDes);
309  public:
310    SYMTAB_EXPORT derivedType();
311    SYMTAB_EXPORT ~derivedType();
312    SYMTAB_EXPORT bool operator==(const Type &) const;
313    SYMTAB_EXPORT Type *getConstituentType() const;
314    SYMTAB_EXPORT void serialize_derived(SerializerBase *, 
315                    const char * = "derivedType") THROW_SPEC(SerializerError);
316 };
317
318 // Derived classes from Type
319
320 class typeEnum : public Type {
321  private:  
322         std::vector<std::pair<std::string, int> > consts;
323  public:
324    SYMTAB_EXPORT typeEnum();
325    SYMTAB_EXPORT typeEnum(typeId_t ID, std::string name = "");
326    SYMTAB_EXPORT typeEnum(std::string name);
327    SYMTAB_EXPORT static typeEnum *create(std::string &name, std::vector<std::pair<std::string, int> *>&elements, 
328                                                                 Symtab *obj = NULL);
329    SYMTAB_EXPORT static typeEnum *create(std::string &name, std::vector<std::string> &constNames, Symtab *obj);
330    SYMTAB_EXPORT bool addConstant(const std::string &fieldname,int value);
331    SYMTAB_EXPORT std::vector<std::pair<std::string, int> > &getConstants();
332    SYMTAB_EXPORT bool setName(const char *name);
333    SYMTAB_EXPORT bool isCompatible(Type *otype);
334    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
335 };
336
337 class typeFunction : public Type {
338  protected:
339    SYMTAB_EXPORT void fixupUnknowns(Module *);
340  private:
341    Type *retType_; /* Return type of the function */
342    std::vector<Type *> params_; 
343  public:
344    SYMTAB_EXPORT typeFunction();
345    SYMTAB_EXPORT typeFunction(typeId_t ID, Type *retType, std::string name = "");
346    SYMTAB_EXPORT typeFunction(Type *retType, std::string name = "");
347    SYMTAB_EXPORT static typeFunction *create(std::string &name, Type *retType, 
348                                 std::vector<Type *> &paramTypes, Symtab *obj = NULL);
349    SYMTAB_EXPORT ~typeFunction();
350    SYMTAB_EXPORT bool addParam( Type *type);
351    SYMTAB_EXPORT Type *getReturnType() const;
352    SYMTAB_EXPORT bool setRetType(Type *rtype);
353
354    SYMTAB_EXPORT std::vector<Type *> &getParams();
355    SYMTAB_EXPORT bool isCompatible(Type *otype);
356    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
357 };
358
359 class typeScalar : public Type {
360  private:
361    bool isSigned_;
362  public:
363    SYMTAB_EXPORT typeScalar();
364    SYMTAB_EXPORT typeScalar(typeId_t ID, unsigned int size, std::string name = "", bool isSigned = false);
365    SYMTAB_EXPORT typeScalar(unsigned int size, std::string name = "", bool isSigned = false);
366    SYMTAB_EXPORT static typeScalar *create(std::string &name, int size, Symtab *obj = NULL);
367    SYMTAB_EXPORT bool isSigned();
368    SYMTAB_EXPORT bool isCompatible(Type *otype);
369    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
370 };
371
372 class typeCommon : public fieldListType {
373  private:
374    std::vector<CBlock *> cblocks;
375  protected:
376    SYMTAB_EXPORT void postFieldInsert(int nsize) { size_ += nsize; }
377    //void postFieldInsert(int offset, int nsize) { if ((unsigned int) (offset + nsize) > size_) size_ = offset + nsize; }
378    SYMTAB_EXPORT void fixupUnknowns(Module *);
379  public:
380    SYMTAB_EXPORT typeCommon();
381    SYMTAB_EXPORT typeCommon(typeId_t ID, std::string name = "");
382    SYMTAB_EXPORT typeCommon(std::string name);
383    SYMTAB_EXPORT static typeCommon *create(std::string &name, Symtab *obj = NULL);
384    SYMTAB_EXPORT std::vector<CBlock *> *getCblocks() const;
385    SYMTAB_EXPORT void beginCommonBlock();
386    SYMTAB_EXPORT void endCommonBlock(Symbol *, void *baseAddr);
387    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
388 };
389
390 class CBlock : public Serializable, public AnnotatableSparse
391 {
392    friend class typeCommon;
393  private:
394    // the list of fields
395    std::vector<Field *> fieldList;
396
397    // which functions use this list
398    //  Should probably be updated to use aggregates
399    std::vector<Symbol *> functions;
400
401  public:
402    SYMTAB_EXPORT std::vector<Field *> *getComponents();
403    SYMTAB_EXPORT std::vector<Symbol *> *getFunctions();
404
405    SYMTAB_EXPORT void fixupUnknowns(Module *);
406    
407    SYMTAB_EXPORT Serializable * serialize_impl(SerializerBase *,
408                    const char *tag="CBlock") THROW_SPEC(SerializerError);
409 };
410
411 class typeStruct : public fieldListType {
412  protected:
413    SYMTAB_EXPORT void updateSize();
414    SYMTAB_EXPORT void postFieldInsert(int nsize);
415    SYMTAB_EXPORT void fixupUnknowns(Module *);
416    SYMTAB_EXPORT void merge(Type *other);
417  public:
418    SYMTAB_EXPORT typeStruct();
419    SYMTAB_EXPORT typeStruct(typeId_t ID, std::string name = "");
420    SYMTAB_EXPORT typeStruct(std::string name);
421    SYMTAB_EXPORT static typeStruct *create(std::string &name, std::vector< std::pair<std::string, Type *> *> &flds,
422
423                                                                 Symtab *obj = NULL);
424    SYMTAB_EXPORT static typeStruct *create(std::string &name, std::vector<Field *> &fields, 
425                                                                 Symtab *obj = NULL);
426
427    SYMTAB_EXPORT bool isCompatible(Type *otype);
428    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
429 };
430
431 class typeUnion : public fieldListType {
432  protected:
433    SYMTAB_EXPORT void updateSize();
434    SYMTAB_EXPORT void postFieldInsert(int nsize);
435    SYMTAB_EXPORT void merge(Type *other);
436    SYMTAB_EXPORT void fixupUnknowns(Module *);
437  public:
438    SYMTAB_EXPORT typeUnion();
439    SYMTAB_EXPORT typeUnion(typeId_t ID, std::string name = "");
440    SYMTAB_EXPORT typeUnion(std::string name);
441    SYMTAB_EXPORT static typeUnion *create(std::string &name, std::vector<std::pair<std::string, Type *> *> &fieldNames,
442                                                         Symtab *obj = NULL);
443    SYMTAB_EXPORT static typeUnion *create(std::string &name, std::vector<Field *> &fields, 
444                                                         Symtab *obj = NULL);
445    SYMTAB_EXPORT bool isCompatible(Type *otype);
446    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
447 };
448
449 class typePointer : public derivedType {
450  protected: 
451    SYMTAB_EXPORT void fixupUnknowns(Module *);
452  public:
453    SYMTAB_EXPORT typePointer();
454    SYMTAB_EXPORT typePointer(typeId_t ID, Type *ptr, std::string name = "");
455    SYMTAB_EXPORT typePointer(Type *ptr, std::string name = "");
456    SYMTAB_EXPORT static typePointer *create(std::string &name, Type *ptr, Symtab *obj = NULL);
457    SYMTAB_EXPORT static typePointer *create(std::string &name, Type *ptr, int size, 
458                                                         Symtab *obj = NULL);
459    SYMTAB_EXPORT bool isCompatible(Type *otype);
460    SYMTAB_EXPORT bool setPtr(Type *ptr);
461    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
462 };
463
464 class typeTypedef: public derivedType {
465  private:
466    unsigned int sizeHint_;
467  
468  protected:
469    SYMTAB_EXPORT void updateSize();
470    SYMTAB_EXPORT void fixupUnknowns(Module *);
471       
472  public:
473    SYMTAB_EXPORT typeTypedef();
474    SYMTAB_EXPORT typeTypedef(typeId_t ID, Type *base, std::string name, unsigned int sizeHint = 0);
475    SYMTAB_EXPORT typeTypedef(Type *base, std::string name, unsigned int sizeHint = 0);
476    
477    SYMTAB_EXPORT static typeTypedef *create(std::string &name, Type *ptr, Symtab *obj = NULL);
478    SYMTAB_EXPORT bool isCompatible(Type *otype);
479    SYMTAB_EXPORT bool operator==(const Type &otype) const;
480    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
481 };
482
483 class typeRef : public derivedType {
484  protected:
485    SYMTAB_EXPORT void fixupUnknowns(Module *);
486  public:
487    SYMTAB_EXPORT typeRef();
488    SYMTAB_EXPORT typeRef(typeId_t ID, Type *refType, std::string name);
489    SYMTAB_EXPORT typeRef(Type *refType, std::string name);
490    SYMTAB_EXPORT static typeRef *create(std::string &name, Type *ptr, Symtab * obj = NULL);
491    SYMTAB_EXPORT bool isCompatible(Type *otype);
492    SYMTAB_EXPORT bool operator==(const Type &otype) const;
493    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
494 };
495
496 class typeSubrange : public rangedType {
497  private:
498    //typeSubrange(int ID, int size, const char *low, const char *hi, const char *name);
499  public:
500    SYMTAB_EXPORT typeSubrange();
501    SYMTAB_EXPORT typeSubrange(typeId_t ID, int size, long low, long hi, std::string name);
502    SYMTAB_EXPORT typeSubrange( int size, long low, long hi, std::string name);
503    SYMTAB_EXPORT static typeSubrange *create(std::string &name, int size, long low, long hi, Symtab *obj = NULL);
504    SYMTAB_EXPORT bool isCompatible(Type *otype);
505    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
506 };
507
508 class typeArray : public rangedType {
509  private:
510    Type *arrayElem;
511    unsigned int sizeHint_;
512  protected:
513    SYMTAB_EXPORT void updateSize();
514    SYMTAB_EXPORT void merge(Type *other); 
515  public:
516    SYMTAB_EXPORT typeArray();
517    SYMTAB_EXPORT typeArray(typeId_t ID, Type *base, long low, long hi, std::string name, unsigned int sizeHint = 0);
518    SYMTAB_EXPORT typeArray(Type *base, long low, long hi, std::string name, unsigned int sizeHint = 0);
519    SYMTAB_EXPORT static typeArray *create(std::string &name, Type *typ,  long low, long hi, Symtab *obj = NULL);
520    SYMTAB_EXPORT Type *getBaseType() const;
521    SYMTAB_EXPORT bool isCompatible(Type *otype);
522    SYMTAB_EXPORT bool operator==(const Type &otype) const;
523    SYMTAB_EXPORT void fixupUnknowns(Module *);
524    SYMTAB_EXPORT void serialize_specific(SerializerBase *) THROW_SPEC(SerializerError);
525 };
526
527 } // namespace SymtabAPI
528 } // namespace Dyninst
529 #endif
530