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