mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 04:38:24 +00:00
Now that all of the derived types have disciplined interfaces, we can eliminate
all of the ad-hoc storage of contained types. This allows getContainedType to not be virtual, and allows us to entirely delete the TypeIterator class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11230 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -19,7 +19,6 @@
|
|||||||
#define LLVM_DERIVED_TYPES_H
|
#define LLVM_DERIVED_TYPES_H
|
||||||
|
|
||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -57,7 +56,7 @@ protected:
|
|||||||
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
||||||
// another (more concrete) type, we must eliminate all references to other
|
// another (more concrete) type, we must eliminate all references to other
|
||||||
// types, to avoid some circular reference problems.
|
// types, to avoid some circular reference problems.
|
||||||
virtual void dropAllTypeUses() = 0;
|
void dropAllTypeUses();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -122,8 +121,6 @@ public:
|
|||||||
|
|
||||||
class FunctionType : public DerivedType {
|
class FunctionType : public DerivedType {
|
||||||
friend class TypeMap<FunctionValType, FunctionType>;
|
friend class TypeMap<FunctionValType, FunctionType>;
|
||||||
PATypeHandle ResultType;
|
|
||||||
std::vector<PATypeHandle> ParamTys;
|
|
||||||
bool isVarArgs;
|
bool isVarArgs;
|
||||||
|
|
||||||
FunctionType(const FunctionType &); // Do not implement
|
FunctionType(const FunctionType &); // Do not implement
|
||||||
@ -137,11 +134,6 @@ protected:
|
|||||||
FunctionType(const Type *Result, const std::vector<const Type*> &Params,
|
FunctionType(const Type *Result, const std::vector<const Type*> &Params,
|
||||||
bool IsVarArgs);
|
bool IsVarArgs);
|
||||||
|
|
||||||
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
|
||||||
// another (more concrete) type, we must eliminate all references to other
|
|
||||||
// types, to avoid some circular reference problems.
|
|
||||||
virtual void dropAllTypeUses();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// FunctionType::get - This static method is the primary way of constructing
|
/// FunctionType::get - This static method is the primary way of constructing
|
||||||
/// a FunctionType
|
/// a FunctionType
|
||||||
@ -150,25 +142,19 @@ public:
|
|||||||
bool isVarArg);
|
bool isVarArg);
|
||||||
|
|
||||||
inline bool isVarArg() const { return isVarArgs; }
|
inline bool isVarArg() const { return isVarArgs; }
|
||||||
inline const Type *getReturnType() const { return ResultType; }
|
inline const Type *getReturnType() const { return ContainedTys[0]; }
|
||||||
|
|
||||||
typedef std::vector<PATypeHandle>::const_iterator param_iterator;
|
typedef std::vector<PATypeHandle>::const_iterator param_iterator;
|
||||||
param_iterator param_begin() const { return ParamTys.begin(); }
|
param_iterator param_begin() const { return ContainedTys.begin()+1; }
|
||||||
param_iterator param_end() const { return ParamTys.end(); }
|
param_iterator param_end() const { return ContainedTys.end(); }
|
||||||
|
|
||||||
// Parameter type accessors...
|
// Parameter type accessors...
|
||||||
const Type *getParamType(unsigned i) const { return ParamTys[i]; }
|
const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
|
||||||
|
|
||||||
// getNumParams - Return the number of fixed parameters this function type
|
// getNumParams - Return the number of fixed parameters this function type
|
||||||
// requires. This does not consider varargs.
|
// requires. This does not consider varargs.
|
||||||
//
|
//
|
||||||
unsigned getNumParams() const { return ParamTys.size(); }
|
unsigned getNumParams() const { return ContainedTys.size()-1; }
|
||||||
|
|
||||||
|
|
||||||
virtual const Type *getContainedType(unsigned i) const {
|
|
||||||
return i == 0 ? ResultType.get() : ParamTys[i-1].get();
|
|
||||||
}
|
|
||||||
virtual unsigned getNumContainedTypes() const { return ParamTys.size()+1; }
|
|
||||||
|
|
||||||
// Implement the AbstractTypeUser interface.
|
// Implement the AbstractTypeUser interface.
|
||||||
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
|
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
|
||||||
@ -213,8 +199,6 @@ public:
|
|||||||
|
|
||||||
class StructType : public CompositeType {
|
class StructType : public CompositeType {
|
||||||
friend class TypeMap<StructValType, StructType>;
|
friend class TypeMap<StructValType, StructType>;
|
||||||
std::vector<PATypeHandle> ETypes; // Element types of struct
|
|
||||||
|
|
||||||
StructType(const StructType &); // Do not implement
|
StructType(const StructType &); // Do not implement
|
||||||
const StructType &operator=(const StructType &); // Do not implement
|
const StructType &operator=(const StructType &); // Do not implement
|
||||||
|
|
||||||
@ -226,11 +210,6 @@ protected:
|
|||||||
// Private ctor - Only can be created by a static member...
|
// Private ctor - Only can be created by a static member...
|
||||||
StructType(const std::vector<const Type*> &Types);
|
StructType(const std::vector<const Type*> &Types);
|
||||||
|
|
||||||
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
|
||||||
// another (more concrete) type, we must eliminate all references to other
|
|
||||||
// types, to avoid some circular reference problems.
|
|
||||||
virtual void dropAllTypeUses();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// StructType::get - This static method is the primary way to create a
|
/// StructType::get - This static method is the primary way to create a
|
||||||
/// StructType.
|
/// StructType.
|
||||||
@ -238,21 +217,16 @@ public:
|
|||||||
|
|
||||||
// Iterator access to the elements
|
// Iterator access to the elements
|
||||||
typedef std::vector<PATypeHandle>::const_iterator element_iterator;
|
typedef std::vector<PATypeHandle>::const_iterator element_iterator;
|
||||||
element_iterator element_begin() const { return ETypes.begin(); }
|
element_iterator element_begin() const { return ContainedTys.begin(); }
|
||||||
element_iterator element_end() const { return ETypes.end(); }
|
element_iterator element_end() const { return ContainedTys.end(); }
|
||||||
|
|
||||||
// Random access to the elements
|
// Random access to the elements
|
||||||
unsigned getNumElements() const { return ETypes.size(); }
|
unsigned getNumElements() const { return ContainedTys.size(); }
|
||||||
const Type *getElementType(unsigned N) const {
|
const Type *getElementType(unsigned N) const {
|
||||||
assert(N < ETypes.size() && "Element number out of range!");
|
assert(N < ContainedTys.size() && "Element number out of range!");
|
||||||
return ETypes[N];
|
return ContainedTys[N];
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const Type *getContainedType(unsigned i) const {
|
|
||||||
return ETypes[i].get();
|
|
||||||
}
|
|
||||||
virtual unsigned getNumContainedTypes() const { return ETypes.size(); }
|
|
||||||
|
|
||||||
// getTypeAtIndex - Given an index value into the type, return the type of the
|
// getTypeAtIndex - Given an index value into the type, return the type of the
|
||||||
// element. For a structure type, this must be a constant value...
|
// element. For a structure type, this must be a constant value...
|
||||||
//
|
//
|
||||||
@ -284,25 +258,19 @@ class SequentialType : public CompositeType {
|
|||||||
SequentialType(const SequentialType &); // Do not implement!
|
SequentialType(const SequentialType &); // Do not implement!
|
||||||
const SequentialType &operator=(const SequentialType &); // Do not implement!
|
const SequentialType &operator=(const SequentialType &); // Do not implement!
|
||||||
protected:
|
protected:
|
||||||
PATypeHandle ElementType;
|
SequentialType(PrimitiveID TID, const Type *ElType) : CompositeType(TID) {
|
||||||
|
ContainedTys.reserve(1);
|
||||||
SequentialType(PrimitiveID TID, const Type *ElType)
|
ContainedTys.push_back(PATypeHandle(ElType, this));
|
||||||
: CompositeType(TID), ElementType(PATypeHandle(ElType, this)) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline const Type *getElementType() const { return ElementType; }
|
inline const Type *getElementType() const { return ContainedTys[0]; }
|
||||||
|
|
||||||
virtual const Type *getContainedType(unsigned i) const {
|
|
||||||
return ElementType.get();
|
|
||||||
}
|
|
||||||
virtual unsigned getNumContainedTypes() const { return 1; }
|
|
||||||
|
|
||||||
// getTypeAtIndex - Given an index value into the type, return the type of the
|
// getTypeAtIndex - Given an index value into the type, return the type of the
|
||||||
// element. For sequential types, there is only one subtype...
|
// element. For sequential types, there is only one subtype...
|
||||||
//
|
//
|
||||||
virtual const Type *getTypeAtIndex(const Value *V) const {
|
virtual const Type *getTypeAtIndex(const Value *V) const {
|
||||||
return ElementType.get();
|
return ContainedTys[0];
|
||||||
}
|
}
|
||||||
virtual bool indexValid(const Value *V) const {
|
virtual bool indexValid(const Value *V) const {
|
||||||
return V->getType()->isInteger();
|
return V->getType()->isInteger();
|
||||||
@ -334,11 +302,6 @@ protected:
|
|||||||
// Private ctor - Only can be created by a static member...
|
// Private ctor - Only can be created by a static member...
|
||||||
ArrayType(const Type *ElType, unsigned NumEl);
|
ArrayType(const Type *ElType, unsigned NumEl);
|
||||||
|
|
||||||
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
|
||||||
// another (more concrete) type, we must eliminate all references to other
|
|
||||||
// types, to avoid some circular reference problems.
|
|
||||||
virtual void dropAllTypeUses();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// ArrayType::get - This static method is the primary way to construct an
|
/// ArrayType::get - This static method is the primary way to construct an
|
||||||
/// ArrayType
|
/// ArrayType
|
||||||
@ -374,10 +337,6 @@ protected:
|
|||||||
// Private ctor - Only can be created by a static member...
|
// Private ctor - Only can be created by a static member...
|
||||||
PointerType(const Type *ElType);
|
PointerType(const Type *ElType);
|
||||||
|
|
||||||
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
|
||||||
// another (more concrete) type, we must eliminate all references to other
|
|
||||||
// types, to avoid some circular reference problems.
|
|
||||||
virtual void dropAllTypeUses();
|
|
||||||
public:
|
public:
|
||||||
/// PointerType::get - This is the only way to construct a new pointer type.
|
/// PointerType::get - This is the only way to construct a new pointer type.
|
||||||
static PointerType *get(const Type *ElementType);
|
static PointerType *get(const Type *ElementType);
|
||||||
@ -408,13 +367,6 @@ protected:
|
|||||||
// Private ctor - Only can be created by a static member...
|
// Private ctor - Only can be created by a static member...
|
||||||
OpaqueType();
|
OpaqueType();
|
||||||
|
|
||||||
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
|
||||||
// another (more concrete) type, we must eliminate all references to other
|
|
||||||
// types, to avoid some circular reference problems.
|
|
||||||
virtual void dropAllTypeUses() {
|
|
||||||
// FIXME: THIS IS NOT AN ABSTRACT TYPE USER!
|
|
||||||
} // No type uses
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// OpaqueType::get - Static factory method for the OpaqueType class...
|
// OpaqueType::get - Static factory method for the OpaqueType class...
|
||||||
static OpaqueType *get() {
|
static OpaqueType *get() {
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "llvm/Value.h"
|
#include "llvm/Value.h"
|
||||||
#include "Support/GraphTraits.h"
|
#include "Support/GraphTraits.h"
|
||||||
#include "Support/iterator"
|
#include "Support/iterator"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -106,6 +107,15 @@ protected:
|
|||||||
/// to the more refined type. Only abstract types can be forwarded.
|
/// to the more refined type. Only abstract types can be forwarded.
|
||||||
mutable const Type *ForwardType;
|
mutable const Type *ForwardType;
|
||||||
|
|
||||||
|
/// ContainedTys - The list of types contained by this one. For example, this
|
||||||
|
/// includes the arguments of a function type, the elements of the structure,
|
||||||
|
/// the pointee of a pointer, etc. Note that keeping this vector in the Type
|
||||||
|
/// class wastes some space for types that do not contain anything (such as
|
||||||
|
/// primitive types). However, keeping it here allows the subtype_* members
|
||||||
|
/// to be implemented MUCH more efficiently, and dynamically very few types do
|
||||||
|
/// not contain any elements (most are derived).
|
||||||
|
std::vector<PATypeHandle> ContainedTys;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void print(std::ostream &O) const;
|
virtual void print(std::ostream &O) const;
|
||||||
|
|
||||||
@ -204,22 +214,22 @@ public:
|
|||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Type Iteration support
|
// Type Iteration support
|
||||||
//
|
//
|
||||||
class TypeIterator;
|
typedef std::vector<PATypeHandle>::const_iterator subtype_iterator;
|
||||||
typedef TypeIterator subtype_iterator;
|
subtype_iterator subtype_begin() const { return ContainedTys.begin(); }
|
||||||
inline subtype_iterator subtype_begin() const; // DEFINED BELOW
|
subtype_iterator subtype_end() const { return ContainedTys.end(); }
|
||||||
inline subtype_iterator subtype_end() const; // DEFINED BELOW
|
|
||||||
|
|
||||||
/// getContainedType - This method is used to implement the type iterator
|
/// getContainedType - This method is used to implement the type iterator
|
||||||
/// (defined a the end of the file). For derived types, this returns the
|
/// (defined a the end of the file). For derived types, this returns the
|
||||||
/// types 'contained' in the derived type.
|
/// types 'contained' in the derived type.
|
||||||
///
|
///
|
||||||
virtual const Type *getContainedType(unsigned i) const {
|
const Type *getContainedType(unsigned i) const {
|
||||||
assert(0 && "No contained types!");
|
assert(i < ContainedTys.size() && "Index out of range!");
|
||||||
return 0;
|
return ContainedTys[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getNumContainedTypes - Return the number of types in the derived type
|
/// getNumContainedTypes - Return the number of types in the derived type.
|
||||||
virtual unsigned getNumContainedTypes() const { return 0; }
|
///
|
||||||
|
unsigned getNumContainedTypes() const { return ContainedTys.size(); }
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Static members exported by the Type class itself. Useful for getting
|
// Static members exported by the Type class itself. Useful for getting
|
||||||
@ -249,50 +259,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "llvm/Type.def"
|
#include "llvm/Type.def"
|
||||||
|
|
||||||
private:
|
|
||||||
class TypeIterator : public bidirectional_iterator<const Type, ptrdiff_t> {
|
|
||||||
const Type * const Ty;
|
|
||||||
unsigned Idx;
|
|
||||||
|
|
||||||
typedef TypeIterator _Self;
|
|
||||||
public:
|
|
||||||
TypeIterator(const Type *ty, unsigned idx) : Ty(ty), Idx(idx) {}
|
|
||||||
~TypeIterator() {}
|
|
||||||
|
|
||||||
const _Self &operator=(const _Self &RHS) {
|
|
||||||
assert(Ty == RHS.Ty && "Cannot assign from different types!");
|
|
||||||
Idx = RHS.Idx;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const _Self& x) const { return Idx == x.Idx; }
|
|
||||||
bool operator!=(const _Self& x) const { return !operator==(x); }
|
|
||||||
|
|
||||||
pointer operator*() const { return Ty->getContainedType(Idx); }
|
|
||||||
pointer operator->() const { return operator*(); }
|
|
||||||
|
|
||||||
_Self& operator++() { ++Idx; return *this; } // Preincrement
|
|
||||||
_Self operator++(int) { // Postincrement
|
|
||||||
_Self tmp = *this; ++*this; return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Self& operator--() { --Idx; return *this; } // Predecrement
|
|
||||||
_Self operator--(int) { // Postdecrement
|
|
||||||
_Self tmp = *this; --*this; return tmp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Type::TypeIterator Type::subtype_begin() const {
|
|
||||||
return TypeIterator(this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Type::TypeIterator Type::subtype_end() const {
|
|
||||||
return TypeIterator(this, getNumContainedTypes());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Provide specializations of GraphTraits to be able to treat a type as a
|
// Provide specializations of GraphTraits to be able to treat a type as a
|
||||||
// graph of sub types...
|
// graph of sub types...
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ const std::string &Type::getDescription() const {
|
|||||||
bool StructType::indexValid(const Value *V) const {
|
bool StructType::indexValid(const Value *V) const {
|
||||||
// Structure indexes require unsigned integer constants.
|
// Structure indexes require unsigned integer constants.
|
||||||
if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(V))
|
if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(V))
|
||||||
return CU->getValue() < ETypes.size();
|
return CU->getValue() < ContainedTys.size();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,9 +271,9 @@ bool StructType::indexValid(const Value *V) const {
|
|||||||
const Type *StructType::getTypeAtIndex(const Value *V) const {
|
const Type *StructType::getTypeAtIndex(const Value *V) const {
|
||||||
assert(isa<Constant>(V) && "Structure index must be a constant!!");
|
assert(isa<Constant>(V) && "Structure index must be a constant!!");
|
||||||
unsigned Idx = cast<ConstantUInt>(V)->getValue();
|
unsigned Idx = cast<ConstantUInt>(V)->getValue();
|
||||||
assert(Idx < ETypes.size() && "Structure index out of range!");
|
assert(Idx < ContainedTys.size() && "Structure index out of range!");
|
||||||
assert(indexValid(V) && "Invalid structure index!"); // Duplicate check
|
assert(indexValid(V) && "Invalid structure index!"); // Duplicate check
|
||||||
return ETypes[Idx];
|
return ContainedTys[Idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -358,12 +358,13 @@ Type *Type::LabelTy = &TheLabelTy;
|
|||||||
FunctionType::FunctionType(const Type *Result,
|
FunctionType::FunctionType(const Type *Result,
|
||||||
const std::vector<const Type*> &Params,
|
const std::vector<const Type*> &Params,
|
||||||
bool IsVarArgs) : DerivedType(FunctionTyID),
|
bool IsVarArgs) : DerivedType(FunctionTyID),
|
||||||
ResultType(PATypeHandle(Result, this)),
|
isVarArgs(IsVarArgs) {
|
||||||
isVarArgs(IsVarArgs) {
|
|
||||||
bool isAbstract = Result->isAbstract();
|
bool isAbstract = Result->isAbstract();
|
||||||
ParamTys.reserve(Params.size());
|
ContainedTys.reserve(Params.size()+1);
|
||||||
for (unsigned i = 0; i < Params.size(); ++i) {
|
ContainedTys.push_back(PATypeHandle(Result, this));
|
||||||
ParamTys.push_back(PATypeHandle(Params[i], this));
|
|
||||||
|
for (unsigned i = 0; i != Params.size(); ++i) {
|
||||||
|
ContainedTys.push_back(PATypeHandle(Params[i], this));
|
||||||
isAbstract |= Params[i]->isAbstract();
|
isAbstract |= Params[i]->isAbstract();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,11 +374,11 @@ FunctionType::FunctionType(const Type *Result,
|
|||||||
|
|
||||||
StructType::StructType(const std::vector<const Type*> &Types)
|
StructType::StructType(const std::vector<const Type*> &Types)
|
||||||
: CompositeType(StructTyID) {
|
: CompositeType(StructTyID) {
|
||||||
ETypes.reserve(Types.size());
|
ContainedTys.reserve(Types.size());
|
||||||
bool isAbstract = false;
|
bool isAbstract = false;
|
||||||
for (unsigned i = 0; i < Types.size(); ++i) {
|
for (unsigned i = 0; i < Types.size(); ++i) {
|
||||||
assert(Types[i] != Type::VoidTy && "Void type in method prototype!!");
|
assert(Types[i] != Type::VoidTy && "Void type in method prototype!!");
|
||||||
ETypes.push_back(PATypeHandle(Types[i], this));
|
ContainedTys.push_back(PATypeHandle(Types[i], this));
|
||||||
isAbstract |= Types[i]->isAbstract();
|
isAbstract |= Types[i]->isAbstract();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,44 +406,22 @@ OpaqueType::OpaqueType() : DerivedType(OpaqueTyID) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dropAllTypeUses - When this (abstract) type is resolved to be equal to
|
||||||
// getAlwaysOpaqueTy - This function returns an opaque type. It doesn't matter
|
// another (more concrete) type, we must eliminate all references to other
|
||||||
// _which_ opaque type it is, but the opaque type must never get resolved.
|
// types, to avoid some circular reference problems.
|
||||||
//
|
void DerivedType::dropAllTypeUses() {
|
||||||
static Type *getAlwaysOpaqueTy() {
|
if (!ContainedTys.empty()) {
|
||||||
static Type *AlwaysOpaqueTy = OpaqueType::get();
|
while (ContainedTys.size() > 1)
|
||||||
static PATypeHolder Holder(AlwaysOpaqueTy);
|
ContainedTys.pop_back();
|
||||||
return AlwaysOpaqueTy;
|
|
||||||
|
// The type must stay abstract. To do this, we insert a pointer to a type
|
||||||
|
// that will never get resolved, thus will always be abstract.
|
||||||
|
static Type *AlwaysOpaqueTy = OpaqueType::get();
|
||||||
|
static PATypeHolder Holder(AlwaysOpaqueTy);
|
||||||
|
ContainedTys[0] = AlwaysOpaqueTy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// dropAllTypeUses methods - These methods eliminate any possibly recursive type
|
|
||||||
// references from a derived type. The type must remain abstract, so we make
|
|
||||||
// sure to use an always opaque type as an argument.
|
|
||||||
//
|
|
||||||
|
|
||||||
void FunctionType::dropAllTypeUses() {
|
|
||||||
ResultType = getAlwaysOpaqueTy();
|
|
||||||
ParamTys.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayType::dropAllTypeUses() {
|
|
||||||
ElementType = getAlwaysOpaqueTy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructType::dropAllTypeUses() {
|
|
||||||
ETypes.clear();
|
|
||||||
ETypes.push_back(PATypeHandle(getAlwaysOpaqueTy(), this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PointerType::dropAllTypeUses() {
|
|
||||||
ElementType = getAlwaysOpaqueTy();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// isTypeAbstract - This is a recursive function that walks a type hierarchy
|
// isTypeAbstract - This is a recursive function that walks a type hierarchy
|
||||||
// calculating whether or not a type is abstract. Worst case it will have to do
|
// calculating whether or not a type is abstract. Worst case it will have to do
|
||||||
// a lot of traversing if you have some whacko opaque types, but in most cases,
|
// a lot of traversing if you have some whacko opaque types, but in most cases,
|
||||||
@ -465,7 +444,7 @@ bool Type::isTypeAbstract() {
|
|||||||
// one!
|
// one!
|
||||||
for (Type::subtype_iterator I = subtype_begin(), E = subtype_end();
|
for (Type::subtype_iterator I = subtype_begin(), E = subtype_end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
if (const_cast<Type*>(*I)->isTypeAbstract()) {
|
if (const_cast<Type*>(I->get())->isTypeAbstract()) {
|
||||||
setAbstract(true); // Restore the abstract bit.
|
setAbstract(true); // Restore the abstract bit.
|
||||||
return true; // This type is abstract if subtype is abstract!
|
return true; // This type is abstract if subtype is abstract!
|
||||||
}
|
}
|
||||||
@ -601,8 +580,8 @@ public:
|
|||||||
for (Type::subtype_iterator I = Ty->subtype_begin(),
|
for (Type::subtype_iterator I = Ty->subtype_begin(),
|
||||||
E = Ty->subtype_end(); I != E; ++I) {
|
E = Ty->subtype_end(); I != E; ++I) {
|
||||||
for (df_ext_iterator<const Type *, std::set<const Type*> >
|
for (df_ext_iterator<const Type *, std::set<const Type*> >
|
||||||
DFI = df_ext_begin(*I, VisitedTypes),
|
DFI = df_ext_begin(I->get(), VisitedTypes),
|
||||||
E = df_ext_end(*I, VisitedTypes); DFI != E; ++DFI)
|
E = df_ext_end(I->get(), VisitedTypes); DFI != E; ++DFI)
|
||||||
if (*DFI == Ty) {
|
if (*DFI == Ty) {
|
||||||
HasTypeCycle = true;
|
HasTypeCycle = true;
|
||||||
goto FoundCycle;
|
goto FoundCycle;
|
||||||
@ -1051,14 +1030,10 @@ void FunctionType::refineAbstractType(const DerivedType *OldType,
|
|||||||
FunctionTypes.getEntryForType(this);
|
FunctionTypes.getEntryForType(this);
|
||||||
|
|
||||||
// Find the type element we are refining...
|
// Find the type element we are refining...
|
||||||
if (ResultType == OldType) {
|
for (unsigned i = 0, e = ContainedTys.size(); i != e; ++i)
|
||||||
ResultType.removeUserFromConcrete();
|
if (ContainedTys[i] == OldType) {
|
||||||
ResultType = NewType;
|
ContainedTys[i].removeUserFromConcrete();
|
||||||
}
|
ContainedTys[i] = NewType;
|
||||||
for (unsigned i = 0, e = ParamTys.size(); i != e; ++i)
|
|
||||||
if (ParamTys[i] == OldType) {
|
|
||||||
ParamTys[i].removeUserFromConcrete();
|
|
||||||
ParamTys[i] = NewType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionTypes.finishRefinement(TMI);
|
FunctionTypes.finishRefinement(TMI);
|
||||||
@ -1088,8 +1063,8 @@ void ArrayType::refineAbstractType(const DerivedType *OldType,
|
|||||||
ArrayTypes.getEntryForType(this);
|
ArrayTypes.getEntryForType(this);
|
||||||
|
|
||||||
assert(getElementType() == OldType);
|
assert(getElementType() == OldType);
|
||||||
ElementType.removeUserFromConcrete();
|
ContainedTys[0].removeUserFromConcrete();
|
||||||
ElementType = NewType;
|
ContainedTys[0] = NewType;
|
||||||
|
|
||||||
ArrayTypes.finishRefinement(TMI);
|
ArrayTypes.finishRefinement(TMI);
|
||||||
}
|
}
|
||||||
@ -1117,12 +1092,12 @@ void StructType::refineAbstractType(const DerivedType *OldType,
|
|||||||
TypeMap<StructValType, StructType>::iterator TMI =
|
TypeMap<StructValType, StructType>::iterator TMI =
|
||||||
StructTypes.getEntryForType(this);
|
StructTypes.getEntryForType(this);
|
||||||
|
|
||||||
for (int i = ETypes.size()-1; i >= 0; --i)
|
for (int i = ContainedTys.size()-1; i >= 0; --i)
|
||||||
if (ETypes[i] == OldType) {
|
if (ContainedTys[i] == OldType) {
|
||||||
ETypes[i].removeUserFromConcrete();
|
ContainedTys[i].removeUserFromConcrete();
|
||||||
|
|
||||||
// Update old type to new type in the array...
|
// Update old type to new type in the array...
|
||||||
ETypes[i] = NewType;
|
ContainedTys[i] = NewType;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructTypes.finishRefinement(TMI);
|
StructTypes.finishRefinement(TMI);
|
||||||
@ -1150,9 +1125,9 @@ void PointerType::refineAbstractType(const DerivedType *OldType,
|
|||||||
TypeMap<PointerValType, PointerType>::iterator TMI =
|
TypeMap<PointerValType, PointerType>::iterator TMI =
|
||||||
PointerTypes.getEntryForType(this);
|
PointerTypes.getEntryForType(this);
|
||||||
|
|
||||||
assert(ElementType == OldType);
|
assert(ContainedTys[0] == OldType);
|
||||||
ElementType.removeUserFromConcrete();
|
ContainedTys[0].removeUserFromConcrete();
|
||||||
ElementType = NewType;
|
ContainedTys[0] = NewType;
|
||||||
|
|
||||||
PointerTypes.finishRefinement(TMI);
|
PointerTypes.finishRefinement(TMI);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user