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