~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/include/llvm/AbstractTypeUser.h

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//===-- llvm/AbstractTypeUser.h - AbstractTypeUser Interface ----*- C++ -*-===//
2
 
//
3
 
//                     The LLVM Compiler Infrastructure
4
 
//
5
 
// This file is distributed under the University of Illinois Open Source
6
 
// License. See LICENSE.TXT for details.
7
 
//
8
 
//===----------------------------------------------------------------------===//
9
 
//
10
 
// This file declares the AbstractTypeUser class.
11
 
//
12
 
//===----------------------------------------------------------------------===//
13
 
 
14
 
#ifndef LLVM_ABSTRACT_TYPE_USER_H
15
 
#define LLVM_ABSTRACT_TYPE_USER_H
16
 
 
17
 
#if !defined(LLVM_TYPE_H) && !defined(LLVM_VALUE_H)
18
 
#error Do not include this file directly.  Include Type.h instead.
19
 
#error Some versions of GCC (e.g. 3.4 and 4.1) can not handle the inlined method
20
 
#error PATypeHolder::dropRef() correctly otherwise.
21
 
#endif
22
 
 
23
 
// This is the "master" include for <cassert> Whether this file needs it or not,
24
 
// it must always include <cassert> for the files which include
25
 
// llvm/AbstractTypeUser.h
26
 
//
27
 
// In this way, most every LLVM source file will have access to the assert()
28
 
// macro without having to #include <cassert> directly.
29
 
//
30
 
#include <cassert>
31
 
 
32
 
namespace llvm {
33
 
 
34
 
class Value;
35
 
class Type;
36
 
class DerivedType;
37
 
template<typename T> struct simplify_type;
38
 
 
39
 
/// The AbstractTypeUser class is an interface to be implemented by classes who
40
 
/// could possibly use an abstract type.  Abstract types are denoted by the
41
 
/// isAbstract flag set to true in the Type class.  These are classes that
42
 
/// contain an Opaque type in their structure somewhere.
43
 
///
44
 
/// Classes must implement this interface so that they may be notified when an
45
 
/// abstract type is resolved.  Abstract types may be resolved into more 
46
 
/// concrete types through: linking, parsing, and bitcode reading.  When this 
47
 
/// happens, all of the users of the type must be updated to reference the new,
48
 
/// more concrete type.  They are notified through the AbstractTypeUser 
49
 
/// interface.
50
 
///
51
 
/// In addition to this, AbstractTypeUsers must keep the use list of the
52
 
/// potentially abstract type that they reference up-to-date.  To do this in a
53
 
/// nice, transparent way, the PATypeHandle class is used to hold "Potentially
54
 
/// Abstract Types", and keep the use list of the abstract types up-to-date.
55
 
/// @brief LLVM Abstract Type User Representation
56
 
class AbstractTypeUser {
57
 
protected:
58
 
  virtual ~AbstractTypeUser();                        // Derive from me
59
 
 
60
 
  /// setType - It's normally not possible to change a Value's type in place,
61
 
  /// but an AbstractTypeUser subclass that knows what its doing can be
62
 
  /// permitted to do so with care.
63
 
  void setType(Value *V, const Type *NewTy);
64
 
 
65
 
public:
66
 
 
67
 
  /// refineAbstractType - The callback method invoked when an abstract type is
68
 
  /// resolved to another type.  An object must override this method to update
69
 
  /// its internal state to reference NewType instead of OldType.
70
 
  ///
71
 
  virtual void refineAbstractType(const DerivedType *OldTy,
72
 
                                  const Type *NewTy) = 0;
73
 
 
74
 
  /// The other case which AbstractTypeUsers must be aware of is when a type
75
 
  /// makes the transition from being abstract (where it has clients on its
76
 
  /// AbstractTypeUsers list) to concrete (where it does not).  This method
77
 
  /// notifies ATU's when this occurs for a type.
78
 
  ///
79
 
  virtual void typeBecameConcrete(const DerivedType *AbsTy) = 0;
80
 
 
81
 
  // for debugging...
82
 
  virtual void dump() const = 0;
83
 
};
84
 
 
85
 
 
86
 
/// PATypeHandle - Handle to a Type subclass.  This class is used to keep the
87
 
/// use list of abstract types up-to-date.
88
 
///
89
 
class PATypeHandle {
90
 
  const Type *Ty;
91
 
  AbstractTypeUser * const User;
92
 
 
93
 
  // These functions are defined at the bottom of Type.h.  See the comment there
94
 
  // for justification.
95
 
  void addUser();
96
 
  void removeUser();
97
 
public:
98
 
  // ctor - Add use to type if abstract.  Note that Ty must not be null
99
 
  inline PATypeHandle(const Type *ty, AbstractTypeUser *user)
100
 
    : Ty(ty), User(user) {
101
 
    addUser();
102
 
  }
103
 
 
104
 
  // ctor - Add use to type if abstract.
105
 
  inline PATypeHandle(const PATypeHandle &T) : Ty(T.Ty), User(T.User) {
106
 
    addUser();
107
 
  }
108
 
 
109
 
  // dtor - Remove reference to type...
110
 
  inline ~PATypeHandle() { removeUser(); }
111
 
 
112
 
  // Automatic casting operator so that the handle may be used naturally
113
 
  inline operator Type *() const { return const_cast<Type*>(Ty); }
114
 
  inline Type *get() const { return const_cast<Type*>(Ty); }
115
 
 
116
 
  // operator= - Allow assignment to handle
117
 
  inline Type *operator=(const Type *ty) {
118
 
    if (Ty != ty) {   // Ensure we don't accidentally drop last ref to Ty
119
 
      removeUser();
120
 
      Ty = ty;
121
 
      addUser();
122
 
    }
123
 
    return get();
124
 
  }
125
 
 
126
 
  // operator= - Allow assignment to handle
127
 
  inline const Type *operator=(const PATypeHandle &T) {
128
 
    return operator=(T.Ty);
129
 
  }
130
 
 
131
 
  inline bool operator==(const Type *ty) {
132
 
    return Ty == ty;
133
 
  }
134
 
 
135
 
  // operator-> - Allow user to dereference handle naturally...
136
 
  inline const Type *operator->() const { return Ty; }
137
 
};
138
 
 
139
 
 
140
 
/// PATypeHolder - Holder class for a potentially abstract type.  This uses
141
 
/// efficient union-find techniques to handle dynamic type resolution.  Unless
142
 
/// you need to do custom processing when types are resolved, you should always
143
 
/// use PATypeHolders in preference to PATypeHandles.
144
 
///
145
 
class PATypeHolder {
146
 
  mutable const Type *Ty;
147
 
  void destroy();
148
 
public:
149
 
  PATypeHolder() : Ty(0) {}
150
 
  PATypeHolder(const Type *ty) : Ty(ty) {
151
 
    addRef();
152
 
  }
153
 
  PATypeHolder(const PATypeHolder &T) : Ty(T.Ty) {
154
 
    addRef();
155
 
  }
156
 
 
157
 
  ~PATypeHolder() { dropRef(); }
158
 
 
159
 
  operator Type *() const { return get(); }
160
 
  Type *get() const;
161
 
 
162
 
  // operator-> - Allow user to dereference handle naturally...
163
 
  Type *operator->() const { return get(); }
164
 
 
165
 
  // operator= - Allow assignment to handle
166
 
  Type *operator=(const Type *ty) {
167
 
    if (Ty != ty) {   // Don't accidentally drop last ref to Ty.
168
 
      dropRef();
169
 
      Ty = ty;
170
 
      addRef();
171
 
    }
172
 
    return get();
173
 
  }
174
 
  Type *operator=(const PATypeHolder &H) {
175
 
    return operator=(H.Ty);
176
 
  }
177
 
 
178
 
  /// getRawType - This should only be used to implement the vmcore library.
179
 
  ///
180
 
  const Type *getRawType() const { return Ty; }
181
 
 
182
 
private:
183
 
  void addRef();
184
 
  void dropRef();
185
 
  friend class TypeMapBase;
186
 
};
187
 
 
188
 
// simplify_type - Allow clients to treat uses just like values when using
189
 
// casting operators.
190
 
template<> struct simplify_type<PATypeHolder> {
191
 
  typedef const Type* SimpleType;
192
 
  static SimpleType getSimplifiedValue(const PATypeHolder &Val) {
193
 
    return static_cast<SimpleType>(Val.get());
194
 
  }
195
 
};
196
 
template<> struct simplify_type<const PATypeHolder> {
197
 
  typedef const Type* SimpleType;
198
 
  static SimpleType getSimplifiedValue(const PATypeHolder &Val) {
199
 
    return static_cast<SimpleType>(Val.get());
200
 
  }
201
 
};
202
 
  
203
 
} // End llvm namespace
204
 
 
205
 
#endif