windows build fixes and some more work on symtab serialization
[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 localVarCollection;
61 class TypeMemManager;
62
63 //TODO?? class BPatch(to be  ??)function;
64
65
66 typedef enum {dataEnum,
67               dataPointer,
68               dataFunction,
69               dataSubrange,
70               dataArray,
71               dataStructure,
72               dataUnion,
73               dataCommon,
74               dataScalar,
75               dataTypedef,
76               dataReference,
77               dataUnknownType,
78               dataNullType,
79               dataTypeClass
80 } dataClass;
81
82 const char *dataClass2Str(dataClass dc);
83
84 typedef int typeId_t;
85
86 typedef enum {
87    visPrivate, 
88    visProtected, 
89    visPublic,
90    visUnknown
91 } visibility_t;
92
93 /*
94  * visibility: Accessibility of member data and functions
95  * These values follow the 'fieldname:' after the '/' identifier.
96  * visPrivate   == 0 gnu Sun -- private
97  * visProtected == 1 gnu Sun -- protected
98  * visPublic    == 2 gnu Sun -- public
99  * visUnknown visibility not known or doesn't apply(ANSIC), the default
100  *
101  */
102  
103 const char *visibility2Str(visibility_t v);
104 #if 0
105
106 typedef enum {
107         storageAddr,
108         storageReg,
109         storageRegOffset
110 } storageClass;
111
112 const char *storageClass2Str(storageClass sc);
113 /*
114  * storageClass: Encodes how a variable is stored.
115  *
116  * storageAddr           - Absolute address of variable.
117  * storageReg            - Register which holds variable value.
118  * storageRegOffset      - Address of variable = $reg + address.
119  */
120
121 typedef enum {
122     storageRef,
123     storageNoRef
124 } storageRefClass;
125         
126 const char *storageRefClass2Str(storageRefClass sc);
127
128 /*
129  * storageRefClass: Encodes if a variable can be accessed through a register/address.
130  *
131  * storageRef        - There is a pointer to variable.
132  * storageNoRef      - No reference. Value can be obtained using storageClass.
133  */
134 #endif
135
136 class SYMTAB_EXPORT Field{
137    friend class typeStruct;
138    friend class typeUnion;
139    friend class typeCommon;
140    friend class CBlock;
141    
142    std::string fieldName_;
143    Type *type_;
144    visibility_t  vis_;
145    int offset_;
146    void *upPtr_;
147
148    /* Method vars */
149  protected:
150    void copy(Field &);
151
152  public:
153    Field(std::string name, Type *typ, int offsetVal = -1, visibility_t vis = visUnknown);
154    
155    // Copy constructor
156    Field(Field &f);
157    ~Field();
158
159    std::string &getName();
160    Type *getType();
161    visibility_t getVisibility();
162    unsigned int getSize();
163    int getOffset();
164    void *getUpPtr() const;
165    bool setUpPtr(void *);
166    
167    void fixupUnknown(Module *);
168 };
169                                   
170 class Type : public Serializable, public AnnotatableSparse  {
171    friend class typeCollection;
172    friend std::string parseStabString(Module *, int linenum, char *, int, 
173                                       typeCommon *);
174    static Type* upgradePlaceholder(Type *placeholder, Type *new_type);
175    public:
176   SYMTAB_EXPORT void serialize(SerializerBase *, const char *) THROW_SPEC (SerializerError);
177  protected:
178    typeId_t ID_;           /* unique ID of type */
179    std::string name_;
180    unsigned int  size_;    /* size of type */
181    dataClass   type_;
182    
183    /**
184     * We set updatingSize to true when we're in the process of
185     * calculating the size of container structures.  This helps avoid
186     * infinite recursion for self referencial types.  Getting a
187     * self-referencial type probably signifies an error in another
188     * part of the type processing code (or an error in the binary).
189     **/
190    bool updatingSize;
191    
192    static typeId_t USER_TYPE_ID;
193
194    // INTERNAL DATA MEMBERS
195    unsigned int refCount;
196
197    //Extend Type
198    void *upPtr_;
199  
200 protected:
201    SYMTAB_EXPORT virtual void updateSize() {}
202
203    SYMTAB_EXPORT virtual void merge( Type * /* other */ ) { }
204
205 public:
206    SYMTAB_EXPORT virtual bool operator==(const Type &) const;
207    SYMTAB_EXPORT virtual bool isCompatible(Type *oType);
208    SYMTAB_EXPORT virtual void fixupUnknowns(Module *);
209
210    SYMTAB_EXPORT Type(std::string name, typeId_t ID, dataClass dataTyp = dataNullType);
211    SYMTAB_EXPORT Type(std::string name, dataClass dataTyp = dataNullType);
212
213    SYMTAB_EXPORT Type();
214    SYMTAB_EXPORT virtual ~Type();
215
216    // A few convenience functions
217    SYMTAB_EXPORT static Type *createFake(std::string name);
218    /* Placeholder for real type, to be filled in later */
219    SYMTAB_EXPORT static Type *createPlaceholder(typeId_t ID, std::string name = "");
220    
221    SYMTAB_EXPORT typeId_t getID() const;
222    SYMTAB_EXPORT unsigned int getSize();
223    SYMTAB_EXPORT bool setSize(unsigned int size);
224    SYMTAB_EXPORT std::string &getName();
225    SYMTAB_EXPORT bool setName(std::string);
226
227    SYMTAB_EXPORT bool setUpPtr(void *);
228    SYMTAB_EXPORT void *getUpPtr() const;
229
230    SYMTAB_EXPORT dataClass getDataClass() const;
231
232    // INTERNAL METHODS
233    SYMTAB_EXPORT void incrRefCount();
234    SYMTAB_EXPORT void decrRefCount(); 
235    //Methods to dynamically cast generic Type Object to specific types.
236    
237    SYMTAB_EXPORT typeEnum *getEnumType();
238    SYMTAB_EXPORT typePointer *getPointerType();
239    SYMTAB_EXPORT typeFunction *getFunctionType();
240    SYMTAB_EXPORT typeSubrange *getSubrangeType();
241    SYMTAB_EXPORT typeArray *getArrayType();
242    SYMTAB_EXPORT typeStruct *getStructType();
243    SYMTAB_EXPORT typeUnion *getUnionType();
244    SYMTAB_EXPORT typeScalar *getScalarType();
245    SYMTAB_EXPORT typeCommon *getCommonType();
246    SYMTAB_EXPORT typeTypedef *getTypedefType();
247    SYMTAB_EXPORT typeRef *getRefType();
248 };
249
250 // Interfaces to be implemented by intermediate subtypes
251 // We have to do this thanks to reference types and C++'s lovely 
252 // multiple inheritance
253
254 class fieldListInterface {
255  public:
256    SYMTAB_EXPORT virtual ~fieldListInterface() {};
257    SYMTAB_EXPORT virtual std::vector<Field *> *getComponents() const = 0;
258 };
259
260 class rangedInterface {
261  public:
262    SYMTAB_EXPORT virtual ~rangedInterface() {};
263    SYMTAB_EXPORT virtual int getLow() const = 0;
264    SYMTAB_EXPORT virtual int getHigh() const  = 0;
265 };  
266
267 class derivedInterface{
268  public:
269    SYMTAB_EXPORT virtual ~derivedInterface() {};
270    SYMTAB_EXPORT virtual Type *getConstituentType() const = 0;
271 };
272
273 // Intermediate types (interfaces + Type)
274
275 class fieldListType : public Type, public fieldListInterface {
276  private:
277    void fixupComponents();
278  protected:
279    std::vector<Field *> fieldList;
280    std::vector<Field *> *derivedFieldList;
281    SYMTAB_EXPORT fieldListType(std::string &name, typeId_t ID, dataClass typeDes);
282    /* Each subclass may need to update its size after adding a field */
283  public:
284    SYMTAB_EXPORT fieldListType();
285    SYMTAB_EXPORT ~fieldListType();
286    SYMTAB_EXPORT bool operator==(const Type &) const;
287    SYMTAB_EXPORT std::vector<Field *> *getComponents() const;
288    
289    SYMTAB_EXPORT std::vector<Field *> *getFields() const;
290    
291    SYMTAB_EXPORT virtual void postFieldInsert(int nsize) = 0;
292    
293    /* Add field for C++ struct or union */
294    SYMTAB_EXPORT void addField(std::string fieldname, Type *type, int offsetVal = -1, visibility_t vis = visUnknown);
295    SYMTAB_EXPORT void addField(unsigned num, std::string fieldname, Type *type, int offsetVal = -1, visibility_t vis = visUnknown);
296    SYMTAB_EXPORT void addField(Field *fld);
297    SYMTAB_EXPORT void addField(unsigned num, Field *fld);
298   
299   // void addField(const std::string &fieldname,  dataClass typeDes, 
300   //               Type *type, int offset, int size, visibility_t vis = visUnknown);
301 };
302
303 class rangedType : public Type, public rangedInterface {
304  protected:
305    int low_;
306    int hi_;
307    //char *low;
308    //char *hi;
309  protected:
310    //rangedType(const std::string &name, typeId_t ID, dataClass typeDes, int size, const char *low, const char *hi); 
311    SYMTAB_EXPORT rangedType(std::string &name, typeId_t ID, dataClass typeDes, int size, int low, int hi);
312    SYMTAB_EXPORT rangedType(std::string &name, dataClass typeDes, int size, int low, int hi);
313  public:
314    SYMTAB_EXPORT rangedType();
315    SYMTAB_EXPORT ~rangedType();
316    SYMTAB_EXPORT bool operator==(const Type &) const;
317    SYMTAB_EXPORT int getLow() const { return low_; }
318    SYMTAB_EXPORT int getHigh() const { return hi_; }
319 };
320
321 class derivedType : public Type, public derivedInterface {
322  protected:
323    Type *baseType_;
324  protected:
325    SYMTAB_EXPORT derivedType(std::string &name, typeId_t id, int size, dataClass typeDes);
326    SYMTAB_EXPORT derivedType(std::string &name, int size, dataClass typeDes);
327  public:
328    SYMTAB_EXPORT derivedType();
329    SYMTAB_EXPORT ~derivedType();
330    SYMTAB_EXPORT bool operator==(const Type &) const;
331    SYMTAB_EXPORT Type *getConstituentType() const;
332 };
333
334 // Derived classes from Type
335
336 class typeEnum : public Type {
337  private:  
338         std::vector<std::pair<std::string, int> *> consts;
339  public:
340    SYMTAB_EXPORT typeEnum();
341    SYMTAB_EXPORT typeEnum(typeId_t ID, std::string name = "");
342    SYMTAB_EXPORT typeEnum(std::string name);
343    SYMTAB_EXPORT static typeEnum *create(std::string &name, std::vector<std::pair<std::string, int> *>&elements, 
344                                                                 Symtab *obj = NULL);
345    SYMTAB_EXPORT static typeEnum *create(std::string &name, std::vector<std::string> &constNames, Symtab *obj);
346    SYMTAB_EXPORT bool addConstant(const std::string &fieldname,int value);
347    SYMTAB_EXPORT std::vector<std::pair<std::string, int> *> &getConstants();
348    SYMTAB_EXPORT bool setName(const char *name);
349    SYMTAB_EXPORT bool isCompatible(Type *otype);
350 };
351
352 class typeFunction : public Type {
353  protected:
354    SYMTAB_EXPORT void fixupUnknowns(Module *);
355  private:
356    Type *retType_; /* Return type of the function */
357    std::vector<Type *> params_; 
358  public:
359    SYMTAB_EXPORT typeFunction();
360    SYMTAB_EXPORT typeFunction(typeId_t ID, Type *retType, std::string name = "");
361    SYMTAB_EXPORT typeFunction(Type *retType, std::string name = "");
362    SYMTAB_EXPORT static typeFunction *create(std::string &name, Type *retType, 
363                                 std::vector<Type *> &paramTypes, Symtab *obj = NULL);
364    SYMTAB_EXPORT ~typeFunction();
365    SYMTAB_EXPORT bool addParam( Type *type);
366    SYMTAB_EXPORT Type *getReturnType() const;
367    SYMTAB_EXPORT bool setRetType(Type *rtype);
368
369    SYMTAB_EXPORT std::vector<Type *> &getParams();
370    SYMTAB_EXPORT bool isCompatible(Type *otype);
371 };
372
373 class typeScalar : public Type {
374  private:
375    bool isSigned_;
376  public:
377    SYMTAB_EXPORT typeScalar();
378    SYMTAB_EXPORT typeScalar(typeId_t ID, unsigned int size, std::string name = "", bool isSigned = false);
379    SYMTAB_EXPORT typeScalar(unsigned int size, std::string name = "", bool isSigned = false);
380    SYMTAB_EXPORT static typeScalar *create(std::string &name, int size, Symtab *obj = NULL);
381    SYMTAB_EXPORT bool isSigned();
382    SYMTAB_EXPORT bool isCompatible(Type *otype);
383 };
384
385 class typeCommon : public fieldListType {
386  private:
387    std::vector<CBlock *> cblocks;
388  protected:
389    SYMTAB_EXPORT void postFieldInsert(int nsize) { size_ += nsize; }
390    //void postFieldInsert(int offset, int nsize) { if ((unsigned int) (offset + nsize) > size_) size_ = offset + nsize; }
391    SYMTAB_EXPORT void fixupUnknowns(Module *);
392  public:
393    SYMTAB_EXPORT typeCommon();
394    SYMTAB_EXPORT typeCommon(typeId_t ID, std::string name = "");
395    SYMTAB_EXPORT typeCommon(std::string name);
396    SYMTAB_EXPORT static typeCommon *create(std::string &name, Symtab *obj = NULL);
397    SYMTAB_EXPORT std::vector<CBlock *> *getCblocks() const;
398    SYMTAB_EXPORT void beginCommonBlock();
399    SYMTAB_EXPORT void endCommonBlock(Symbol *, void *baseAddr);
400 };
401
402 class CBlock{
403    friend class typeCommon;
404  private:
405    // the list of fields
406    std::vector<Field *> fieldList;
407
408    // which functions use this list
409    std::vector<Symbol *> functions;
410
411    void *upPtr_;
412  
413  public:
414    SYMTAB_EXPORT std::vector<Field *> *getComponents();
415    SYMTAB_EXPORT std::vector<Symbol *> *getFunctions();
416
417    SYMTAB_EXPORT void fixupUnknowns(Module *);
418    
419    SYMTAB_EXPORT void *getUpPtr() const;
420    SYMTAB_EXPORT bool setUpPtr(void *);
421 };
422
423 class typeStruct : public fieldListType {
424  protected:
425    SYMTAB_EXPORT void updateSize();
426    SYMTAB_EXPORT void postFieldInsert(int nsize);
427    SYMTAB_EXPORT void fixupUnknowns(Module *);
428    SYMTAB_EXPORT void merge(Type *other);
429  public:
430    SYMTAB_EXPORT typeStruct();
431    SYMTAB_EXPORT typeStruct(typeId_t ID, std::string name = "");
432    SYMTAB_EXPORT typeStruct(std::string name);
433    SYMTAB_EXPORT static typeStruct *create(std::string &name, std::vector< std::pair<std::string, Type *> *> &flds,
434
435                                                                 Symtab *obj = NULL);
436    SYMTAB_EXPORT static typeStruct *create(std::string &name, std::vector<Field *> &fields, 
437                                                                 Symtab *obj = NULL);
438
439    SYMTAB_EXPORT bool isCompatible(Type *otype);
440 };
441
442 class typeUnion : public fieldListType {
443  protected:
444    SYMTAB_EXPORT void updateSize();
445    SYMTAB_EXPORT void postFieldInsert(int nsize);
446    SYMTAB_EXPORT void merge(Type *other);
447    SYMTAB_EXPORT void fixupUnknowns(Module *);
448  public:
449    SYMTAB_EXPORT typeUnion();
450    SYMTAB_EXPORT typeUnion(typeId_t ID, std::string name = "");
451    SYMTAB_EXPORT typeUnion(std::string name);
452    SYMTAB_EXPORT static typeUnion *create(std::string &name, std::vector<std::pair<std::string, Type *> *> &fieldNames,
453                                                         Symtab *obj = NULL);
454    SYMTAB_EXPORT static typeUnion *create(std::string &name, std::vector<Field *> &fields, 
455                                                         Symtab *obj = NULL);
456    SYMTAB_EXPORT bool isCompatible(Type *otype);
457 };
458
459 class typePointer : public derivedType {
460  protected: 
461    SYMTAB_EXPORT void fixupUnknowns(Module *);
462  public:
463    SYMTAB_EXPORT typePointer();
464    SYMTAB_EXPORT typePointer(typeId_t ID, Type *ptr, std::string name = "");
465    SYMTAB_EXPORT typePointer(Type *ptr, std::string name = "");
466    SYMTAB_EXPORT static typePointer *create(std::string &name, Type *ptr, Symtab *obj = NULL);
467    SYMTAB_EXPORT static typePointer *create(std::string &name, Type *ptr, int size, 
468                                                         Symtab *obj = NULL);
469    SYMTAB_EXPORT bool isCompatible(Type *otype);
470    SYMTAB_EXPORT bool setPtr(Type *ptr);
471 };
472
473 class typeTypedef: public derivedType {
474  private:
475    unsigned int sizeHint_;
476  
477  protected:
478    SYMTAB_EXPORT void updateSize();
479    SYMTAB_EXPORT void fixupUnknowns(Module *);
480       
481  public:
482    SYMTAB_EXPORT typeTypedef();
483    SYMTAB_EXPORT typeTypedef(typeId_t ID, Type *base, std::string name, unsigned int sizeHint = 0);
484    SYMTAB_EXPORT typeTypedef(Type *base, std::string name, unsigned int sizeHint = 0);
485    
486    SYMTAB_EXPORT static typeTypedef *create(std::string &name, Type *ptr, Symtab *obj = NULL);
487    SYMTAB_EXPORT bool isCompatible(Type *otype);
488    SYMTAB_EXPORT bool operator==(const Type &otype) const;
489 };
490
491 class typeRef : public derivedType {
492  protected:
493    SYMTAB_EXPORT void fixupUnknowns(Module *);
494  public:
495    SYMTAB_EXPORT typeRef();
496    SYMTAB_EXPORT typeRef(typeId_t ID, Type *refType, std::string name);
497    SYMTAB_EXPORT typeRef(Type *refType, std::string name);
498    SYMTAB_EXPORT static typeRef *create(std::string &name, Type *ptr, Symtab * obj = NULL);
499    SYMTAB_EXPORT bool isCompatible(Type *otype);
500    SYMTAB_EXPORT bool operator==(const Type &otype) const;
501 };
502
503 class typeSubrange : public rangedType {
504  private:
505    //typeSubrange(int ID, int size, const char *low, const char *hi, const char *name);
506  public:
507    SYMTAB_EXPORT typeSubrange();
508    SYMTAB_EXPORT typeSubrange(typeId_t ID, int size, int low, int hi, std::string name);
509    SYMTAB_EXPORT typeSubrange( int size, int low, int hi, std::string name);
510    SYMTAB_EXPORT static typeSubrange *create(std::string &name, int size, int low, int hi, Symtab *obj = NULL);
511    SYMTAB_EXPORT bool isCompatible(Type *otype);
512 };
513
514 class typeArray : public rangedType {
515  private:
516    Type *arrayElem;
517    unsigned int sizeHint_;
518  protected:
519    SYMTAB_EXPORT void updateSize();
520    SYMTAB_EXPORT void merge(Type *other); 
521  public:
522    SYMTAB_EXPORT typeArray();
523    SYMTAB_EXPORT typeArray(typeId_t ID, Type *base, int low, int hi, std::string name, unsigned int sizeHint = 0);
524    SYMTAB_EXPORT typeArray(Type *base, int low, int hi, std::string name, unsigned int sizeHint = 0);
525    SYMTAB_EXPORT static typeArray *create(std::string &name, Type *typ,  int low, int hi, Symtab *obj = NULL);
526    SYMTAB_EXPORT Type *getBaseType() const;
527    SYMTAB_EXPORT bool isCompatible(Type *otype);
528    SYMTAB_EXPORT bool operator==(const Type &otype) const;
529    SYMTAB_EXPORT void fixupUnknowns(Module *);
530 };
531
532 #if 0
533 //location for a variable
534 typedef struct {
535    storageClass stClass;
536    storageRefClass refClass;
537    int reg;
538    long frameOffset;
539    Address lowPC;
540    Address hiPC;
541 } loc_t;
542 #endif
543
544 #if 0
545 class SYMTAB_EXPORT localVar
546 {
547    friend class typeCommon;
548    friend class localVarCollection;
549  
550     std::string name_;
551     Type *type_;
552     std::string fileName_;
553     int lineNum_;
554     std::vector<loc_t> *locs_;
555     void *upPtr_;
556     
557     // scope_t scope;
558   
559   public:
560     localVar() {}
561       //  Internal use only
562       localVar(std::string name,  Type *typ, std::string fileName, int lineNum, std::vector<loc_t> *locs = NULL);
563       // Copy constructor
564       localVar(localVar &lvar);
565       bool addLocation(loc_t *location);
566       bool setLocation(std::vector<loc_t> &locs);
567       ~localVar();
568       void fixupUnknown(Module *);
569  public:
570       //  end of functions for internal use only
571       std::string &getName();
572       Type *getType();
573       bool setType(Type *newType);
574       int  getLineNum();
575       std::string &getFileName();
576       std::vector<loc_t> *getLocationLists();
577
578       void *getUpPtr() const;
579       bool setUpPtr(void *);
580 };
581 #endif
582
583 } // namespace SymtabAPI
584 } // namespace Dyninst
585 #endif