//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_ABSTRACT_TYPE_USER_H
#define LLVM_ABSTRACT_TYPE_USER_H
-// IMPORTANT: Do not include this file directly. Include Type.h instead.
-// Some versions of GCC can't handle the inlined method PATypeHolder::dropRef()
-// correctly otherwise.
+#if !defined(LLVM_TYPE_H) && !defined(LLVM_VALUE_H)
+#error Do not include this file directly. Include Type.h instead.
+#error Some versions of GCC (e.g. 3.4 and 4.1) can not handle the inlined method
+#error PATypeHolder::dropRef() correctly otherwise.
+#endif
// This is the "master" include for <cassert> Whether this file needs it or not,
// it must always include <cassert> for the files which include
namespace llvm {
+class Value;
class Type;
class DerivedType;
+template<typename T> struct simplify_type;
/// The AbstractTypeUser class is an interface to be implemented by classes who
/// could possibly use an abstract type. Abstract types are denoted by the
///
/// Classes must implement this interface so that they may be notified when an
/// abstract type is resolved. Abstract types may be resolved into more
-/// concrete types through: linking, parsing, and bytecode reading. When this
+/// concrete types through: linking, parsing, and bitcode reading. When this
/// happens, all of the users of the type must be updated to reference the new,
/// more concrete type. They are notified through the AbstractTypeUser
/// interface.
class AbstractTypeUser {
protected:
virtual ~AbstractTypeUser(); // Derive from me
+
+ /// setType - It's normally not possible to change a Value's type in place,
+ /// but an AbstractTypeUser subclass that knows what its doing can be
+ /// permitted to do so with care.
+ void setType(Value *V, const Type *NewTy);
+
public:
/// refineAbstractType - The callback method invoked when an abstract type is
const Type *NewTy) = 0;
/// The other case which AbstractTypeUsers must be aware of is when a type
- /// makes the transition from being abstract (where it has clients on it's
+ /// makes the transition from being abstract (where it has clients on its
/// AbstractTypeUsers list) to concrete (where it does not). This method
/// notifies ATU's when this occurs for a type.
///
///
class PATypeHolder {
mutable const Type *Ty;
+ void destroy();
public:
PATypeHolder(const Type *ty) : Ty(ty) {
addRef();
addRef();
}
- ~PATypeHolder() { dropRef(); }
+ ~PATypeHolder() { if (Ty) dropRef(); }
operator Type *() const { return get(); }
Type *get() const;
private:
void addRef();
void dropRef();
+ friend class TypeMapBase;
};
+// simplify_type - Allow clients to treat uses just like values when using
+// casting operators.
+template<> struct simplify_type<PATypeHolder> {
+ typedef const Type* SimpleType;
+ static SimpleType getSimplifiedValue(const PATypeHolder &Val) {
+ return static_cast<SimpleType>(Val.get());
+ }
+};
+template<> struct simplify_type<const PATypeHolder> {
+ typedef const Type* SimpleType;
+ static SimpleType getSimplifiedValue(const PATypeHolder &Val) {
+ return static_cast<SimpleType>(Val.get());
+ }
+};
+
} // End llvm namespace
#endif