#ifndef LLVM_TYPE_H
#define LLVM_TYPE_H
-#include "AbstractTypeUser.h"
+#include "llvm/AbstractTypeUser.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator"
+#include <string>
#include <vector>
namespace llvm {
class PointerType;
class StructType;
class PackedType;
+class TypeMapBase;
-class Type {
+class Type : public AbstractTypeUser {
public:
///===-------------------------------------------------------------------===//
/// Definitions of all of the base types for the Type system. Based on this
private:
TypeID ID : 8; // The current base type of this type.
- bool Abstract; // True if type contains an OpaqueType
+ bool Abstract : 1; // True if type contains an OpaqueType
/// RefCount - This counts the number of PATypeHolders that are pointing to
/// this type. When this number falls to zero, if the type is abstract and
const Type *getForwardedTypeInternal() const;
protected:
- Type(const std::string& Name, TypeID id);
- virtual ~Type() {}
+ Type(const char *Name, TypeID id);
+ Type(TypeID id) : ID(id), Abstract(false), RefCount(0), ForwardType(0) {}
+ virtual ~Type() {
+ assert(AbstractTypeUsers.empty());
+ }
/// Types can become nonabstract later, if they are refined.
///
inline void setAbstract(bool Val) { Abstract = Val; }
- // PromoteAbstractToConcrete - This is an internal method used to calculate
- // change "Abstract" from true to false when types are refined.
- void PromoteAbstractToConcrete();
-
unsigned getRefCount() const { return RefCount; }
/// ForwardType - This field is used to implement the union find scheme for
/// not contain any elements (most are derived).
std::vector<PATypeHandle> ContainedTys;
+ /// AbstractTypeUsers - Implement a list of the users that need to be notified
+ /// if I am a type, and I get resolved into a more concrete type.
+ ///
+ mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
public:
void print(std::ostream &O) const;
/// return zero if the type does not have a size or is not a primitive type.
///
unsigned getPrimitiveSize() const;
+ unsigned getPrimitiveSizeInBits() const;
/// getUnsignedVersion - If this is an integer type, return the unsigned
/// variant of this type. For example int -> uint.
/// getSignedVersion - If this is an integer type, return the signed variant
/// of this type. For example uint -> int.
const Type *getSignedVersion() const;
+
+ /// getIntegralTypeMask - Return a bitmask with ones set for all of the bits
+ /// that can be set by an unsigned version of this type. This is 0xFF for
+ /// sbyte/ubyte, 0xFFFF for shorts, etc.
+ uint64_t getIntegralTypeMask() const {
+ assert(isIntegral() && "This only works for integral types!");
+ return ~0ULL >> (64-getPrimitiveSizeInBits());
+ }
/// getForwaredType - Return the type that this type has been resolved to if
/// it has been resolved to anything. This is used to implement the
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Type *T) { return true; }
-#include "llvm/Type.def"
-
- // Virtual methods used by callbacks below. These should only be implemented
- // in the DerivedType class.
- virtual void addAbstractTypeUser(AbstractTypeUser *U) const {
- abort(); // Only on derived types!
- }
- virtual void removeAbstractTypeUser(AbstractTypeUser *U) const {
- abort(); // Only on derived types!
- }
-
void addRef() const {
assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
++RefCount;
// If this is the last PATypeHolder using this object, and there are no
// PATypeHandles using it, the type is dead, delete it now.
- if (--RefCount == 0)
- RefCountIsZero();
+ if (--RefCount == 0 && AbstractTypeUsers.empty())
+ delete this;
}
+
+ /// addAbstractTypeUser - Notify an abstract type that there is a new user of
+ /// it. This function is called primarily by the PATypeHandle class.
+ ///
+ void addAbstractTypeUser(AbstractTypeUser *U) const {
+ assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
+ AbstractTypeUsers.push_back(U);
+ }
+
+ /// removeAbstractTypeUser - Notify an abstract type that a user of the class
+ /// no longer has a handle to the type. This function is called primarily by
+ /// the PATypeHandle class. When there are no users of the abstract type, it
+ /// is annihilated, because there is no way to get a reference to it ever
+ /// again.
+ ///
+ void removeAbstractTypeUser(AbstractTypeUser *U) const;
/// clearAllTypeMaps - This method frees all internal memory used by the
/// type subsystem, which can be used in environments where this memory is
/// their size is relatively uncommon, move this operation out of line.
bool isSizedDerivedType() const;
- virtual void RefCountIsZero() const {
- abort(); // only on derived types!
- }
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+protected:
+ // PromoteAbstractToConcrete - This is an internal method used to calculate
+ // change "Abstract" from true to false when types are refined.
+ void PromoteAbstractToConcrete();
+ friend class TypeMapBase;
};
//===----------------------------------------------------------------------===//
Ty->removeAbstractTypeUser(User);
}
-inline void PATypeHandle::removeUserFromConcrete() {
- if (!Ty->isAbstract())
- Ty->removeAbstractTypeUser(User);
-}
-
// Define inline methods for PATypeHolder...
inline void PATypeHolder::addRef() {