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