// type is ever created. Thus seeing if two types are equal is a matter of
// doing a trivial pointer comparison.
//
-// Types, once allocated, are never free'd.
+// Types, once allocated, are never free'd, unless they are an abstract type
+// that is resolved to a more concrete type.
//
// Opaque types are simple derived types with no state. There may be many
// different Opaque type objects floating around, but two are only considered
#ifndef LLVM_TYPE_H
#define LLVM_TYPE_H
-#include "llvm/Value.h"
-#include "Support/GraphTraits.h"
-#include "Support/iterator"
+#include "AbstractTypeUser.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
#include <vector>
namespace llvm {
+class ArrayType;
class DerivedType;
class FunctionType;
-class ArrayType;
+class OpaqueType;
class PointerType;
class StructType;
-class OpaqueType;
+class PackedType;
-struct Type : public Value {
+class Type {
+public:
///===-------------------------------------------------------------------===//
/// Definitions of all of the base types for the Type system. Based on this
/// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h)
/// Type::getPrimitiveType function, or else things will break!
///
enum TypeID {
+ // PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date
VoidTyID = 0 , BoolTyID, // 0, 1: Basics...
UByteTyID , SByteTyID, // 2, 3: 8 bit types...
UShortTyID , ShortTyID, // 4, 5: 16 bit types...
UIntTyID , IntTyID, // 6, 7: 32 bit types...
ULongTyID , LongTyID, // 8, 9: 64 bit types...
-
FloatTyID , DoubleTyID, // 10,11: Floating point types...
-
- TypeTyID, // 12 : Type definitions
- LabelTyID , // 13 : Labels...
+ LabelTyID , // 12 : Labels...
// Derived types... see DerivedTypes.h file...
// Make sure FirstDerivedTyID stays up to date!!!
FunctionTyID , StructTyID, // Functions... Structs...
ArrayTyID , PointerTyID, // Array... pointer...
OpaqueTyID, // Opaque type instances...
- //PackedTyID , // SIMD 'packed' format... TODO
+ PackedTyID, // SIMD 'packed' format...
//...
NumTypeIDs, // Must remain as last defined ID
+ LastPrimitiveTyID = LabelTyID,
FirstDerivedTyID = FunctionTyID,
};
private:
- TypeID ID; // The current base type of this type...
- unsigned UID; // The unique ID number for this class
+ TypeID ID : 8; // The current base type of this type.
bool Abstract; // True if type contains an OpaqueType
/// RefCount - This counts the number of PATypeHolders that are pointing to
const Type *getForwardedTypeInternal() const;
protected:
- /// ctor is protected, so only subclasses can create Type objects...
- Type(const std::string &Name, TypeID id);
+ Type(const std::string& Name, TypeID id);
virtual ~Type() {}
-
/// Types can become nonabstract later, if they are refined.
///
inline void setAbstract(bool Val) { Abstract = Val; }
- /// isTypeAbstract - This method is used to calculate the Abstract bit.
- ///
- bool isTypeAbstract();
+ // 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; }
/// @brief Debugging support: print to stderr
virtual void dump() const;
- /// setName - Associate the name with this type in the symbol table, but don't
- /// set the local name to be equal specified name.
- ///
- virtual void setName(const std::string &Name, SymbolTable *ST = 0);
-
//===--------------------------------------------------------------------===//
// Property accessors for dealing with types... Some of these virtual methods
// are defined in private classes defined in Type.cpp for primitive types.
///
inline TypeID getTypeID() const { return ID; }
- /// getUniqueID - Returns the UID of the type. This can be thought of as a
- /// small integer version of the pointer to the type class. Two types that
- /// are structurally different have different UIDs. This can be used for
- /// indexing types into an array.
- ///
- inline unsigned getUniqueID() const { return UID; }
-
/// getDescription - Return the string representation of the type...
const std::string &getDescription() const;
/// true for SByteTy, ShortTy, IntTy, LongTy. Note that this is not true for
/// Float and Double.
///
- virtual bool isSigned() const { return 0; }
+ bool isSigned() const {
+ return ID == SByteTyID || ID == ShortTyID ||
+ ID == IntTyID || ID == LongTyID;
+ }
/// isUnsigned - Return whether a numeric type is unsigned. This is not quite
/// the complement of isSigned... nonnumeric types return false as they do
/// with isSigned. This returns true for UByteTy, UShortTy, UIntTy, and
/// ULongTy
///
- virtual bool isUnsigned() const { return 0; }
+ bool isUnsigned() const {
+ return ID == UByteTyID || ID == UShortTyID ||
+ ID == UIntTyID || ID == ULongTyID;
+ }
- /// isInteger - Equilivent to isSigned() || isUnsigned(), but with only a
- /// single virtual function invocation.
+ /// isInteger - Equivalent to isSigned() || isUnsigned()
///
- virtual bool isInteger() const { return 0; }
+ bool isInteger() const { return ID >= UByteTyID && ID <= LongTyID; }
/// isIntegral - Returns true if this is an integral type, which is either
/// BoolTy or one of the Integer types.
/// Here are some useful little methods to query what type derived types are
/// Note that all other types can just compare to see if this == Type::xxxTy;
///
- inline bool isPrimitiveType() const { return ID < FirstDerivedTyID; }
+ inline bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; }
inline bool isDerivedType() const { return ID >= FirstDerivedTyID; }
/// isFirstClassType - Return true if the value is holdable in a register.
+ ///
inline bool isFirstClassType() const {
- return (ID != VoidTyID && ID < TypeTyID) || ID == PointerTyID;
+ return (ID != VoidTyID && ID <= LastPrimitiveTyID) ||
+ ID == PointerTyID || ID == PackedTyID;
}
/// isSized - Return true if it makes sense to take the size of this type. To
/// TargetData subsystem to do this.
///
bool isSized() const {
- return ID != VoidTyID && ID != TypeTyID &&
- ID != FunctionTyID && ID != LabelTyID && ID != OpaqueTyID;
+ return (ID >= BoolTyID && ID <= DoubleTyID) || ID == PointerTyID ||
+ isSizedDerivedType();
}
- /// getPrimitiveSize - Return the basic size of this type if it is a primative
+ /// getPrimitiveSize - Return the basic size of this type if it is a primitive
/// type. These are fixed by LLVM and are not target dependent. This will
/// return zero if the type does not have a size or is not a primitive type.
///
// instances of Type.
//
- /// getPrimitiveType/getUniqueIDType - Return a type based on an identifier.
+ /// getPrimitiveType - Return a type based on an identifier.
static const Type *getPrimitiveType(TypeID IDNumber);
- static const Type *getUniqueIDType(unsigned UID);
//===--------------------------------------------------------------------===//
// These are the builtin types that are always available...
*LongTy , *ULongTy;
static Type *FloatTy, *DoubleTy;
- static Type *TypeTy , *LabelTy;
+ static Type* LabelTy;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Type *T) { return true; }
- static inline bool classof(const Value *V) {
- return V->getValueType() == Value::TypeVal;
- }
#include "llvm/Type.def"
}
void dropRef() const {
- assert(isAbstract() && "Cannot drop a refernce to a non-abstract type!");
+ assert(isAbstract() && "Cannot drop a reference to a non-abstract type!");
assert(RefCount && "No objects are currently referencing this object!");
// If this is the last PATypeHolder using this object, and there are no
if (--RefCount == 0)
RefCountIsZero();
}
+
+ /// clearAllTypeMaps - This method frees all internal memory used by the
+ /// type subsystem, which can be used in environments where this memory is
+ /// otherwise reported as a leak.
+ static void clearAllTypeMaps();
+
private:
+ /// isSizedDerivedType - Derived types like structures and arrays are sized
+ /// iff all of the members of the type are sized as well. Since asking for
+ /// their size is relatively uncommon, move this operation out of line.
+ bool isSizedDerivedType() const;
+
virtual void RefCountIsZero() const {
abort(); // only on derived types!
}
/// type we are pointing to is forwarding to a new type. If so, we drop our
/// reference to the type.
///
-inline const Type* PATypeHolder::get() const {
+inline Type* PATypeHolder::get() const {
const Type *NewTy = Ty->getForwardedType();
- if (!NewTy) return Ty;
+ if (!NewTy) return const_cast<Type*>(Ty);
return *const_cast<PATypeHolder*>(this) = NewTy;
}
return Ty.getTypeID() == Type::PointerTyID;
}
+std::ostream &operator<<(std::ostream &OS, const Type &T);
+
} // End llvm namespace
#endif