aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/VMCore/Type.cpp107
1 files changed, 41 insertions, 66 deletions
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index d649d08b4c..5a8e2d90b1 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -261,7 +261,7 @@ const std::string &Type::getDescription() const {
bool StructType::indexValid(const Value *V) const {
// Structure indexes require unsigned integer constants.
if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(V))
- return CU->getValue() < ETypes.size();
+ return CU->getValue() < ContainedTys.size();
return false;
}
@@ -271,9 +271,9 @@ bool StructType::indexValid(const Value *V) const {
const Type *StructType::getTypeAtIndex(const Value *V) const {
assert(isa<Constant>(V) && "Structure index must be a constant!!");
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
- return ETypes[Idx];
+ return ContainedTys[Idx];
}
@@ -358,12 +358,13 @@ Type *Type::LabelTy = &TheLabelTy;
FunctionType::FunctionType(const Type *Result,
const std::vector<const Type*> &Params,
bool IsVarArgs) : DerivedType(FunctionTyID),
- ResultType(PATypeHandle(Result, this)),
- isVarArgs(IsVarArgs) {
+ isVarArgs(IsVarArgs) {
bool isAbstract = Result->isAbstract();
- ParamTys.reserve(Params.size());
- for (unsigned i = 0; i < Params.size(); ++i) {
- ParamTys.push_back(PATypeHandle(Params[i], this));
+ ContainedTys.reserve(Params.size()+1);
+ ContainedTys.push_back(PATypeHandle(Result, this));
+
+ for (unsigned i = 0; i != Params.size(); ++i) {
+ ContainedTys.push_back(PATypeHandle(Params[i], this));
isAbstract |= Params[i]->isAbstract();
}
@@ -373,11 +374,11 @@ FunctionType::FunctionType(const Type *Result,
StructType::StructType(const std::vector<const Type*> &Types)
: CompositeType(StructTyID) {
- ETypes.reserve(Types.size());
+ ContainedTys.reserve(Types.size());
bool isAbstract = false;
for (unsigned i = 0; i < Types.size(); ++i) {
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();
}
@@ -405,44 +406,22 @@ OpaqueType::OpaqueType() : DerivedType(OpaqueTyID) {
#endif
}
-
-// getAlwaysOpaqueTy - This function returns an opaque type. It doesn't matter
-// _which_ opaque type it is, but the opaque type must never get resolved.
-//
-static Type *getAlwaysOpaqueTy() {
- static Type *AlwaysOpaqueTy = OpaqueType::get();
- static PATypeHolder Holder(AlwaysOpaqueTy);
- return 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();
+// 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.
+void DerivedType::dropAllTypeUses() {
+ if (!ContainedTys.empty()) {
+ while (ContainedTys.size() > 1)
+ ContainedTys.pop_back();
+
+ // 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;
+ }
}
-
-
-
// 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
// a lot of traversing if you have some whacko opaque types, but in most cases,
@@ -465,7 +444,7 @@ bool Type::isTypeAbstract() {
// one!
for (Type::subtype_iterator I = subtype_begin(), E = subtype_end();
I != E; ++I)
- if (const_cast<Type*>(*I)->isTypeAbstract()) {
+ if (const_cast<Type*>(I->get())->isTypeAbstract()) {
setAbstract(true); // Restore the abstract bit.
return true; // This type is abstract if subtype is abstract!
}
@@ -601,8 +580,8 @@ public:
for (Type::subtype_iterator I = Ty->subtype_begin(),
E = Ty->subtype_end(); I != E; ++I) {
for (df_ext_iterator<const Type *, std::set<const Type*> >
- DFI = df_ext_begin(*I, VisitedTypes),
- E = df_ext_end(*I, VisitedTypes); DFI != E; ++DFI)
+ DFI = df_ext_begin(I->get(), VisitedTypes),
+ E = df_ext_end(I->get(), VisitedTypes); DFI != E; ++DFI)
if (*DFI == Ty) {
HasTypeCycle = true;
goto FoundCycle;
@@ -1051,14 +1030,10 @@ void FunctionType::refineAbstractType(const DerivedType *OldType,
FunctionTypes.getEntryForType(this);
// Find the type element we are refining...
- if (ResultType == OldType) {
- ResultType.removeUserFromConcrete();
- ResultType = NewType;
- }
- for (unsigned i = 0, e = ParamTys.size(); i != e; ++i)
- if (ParamTys[i] == OldType) {
- ParamTys[i].removeUserFromConcrete();
- ParamTys[i] = NewType;
+ for (unsigned i = 0, e = ContainedTys.size(); i != e; ++i)
+ if (ContainedTys[i] == OldType) {
+ ContainedTys[i].removeUserFromConcrete();
+ ContainedTys[i] = NewType;
}
FunctionTypes.finishRefinement(TMI);
@@ -1088,8 +1063,8 @@ void ArrayType::refineAbstractType(const DerivedType *OldType,
ArrayTypes.getEntryForType(this);
assert(getElementType() == OldType);
- ElementType.removeUserFromConcrete();
- ElementType = NewType;
+ ContainedTys[0].removeUserFromConcrete();
+ ContainedTys[0] = NewType;
ArrayTypes.finishRefinement(TMI);
}
@@ -1117,12 +1092,12 @@ void StructType::refineAbstractType(const DerivedType *OldType,
TypeMap<StructValType, StructType>::iterator TMI =
StructTypes.getEntryForType(this);
- for (int i = ETypes.size()-1; i >= 0; --i)
- if (ETypes[i] == OldType) {
- ETypes[i].removeUserFromConcrete();
+ for (int i = ContainedTys.size()-1; i >= 0; --i)
+ if (ContainedTys[i] == OldType) {
+ ContainedTys[i].removeUserFromConcrete();
// Update old type to new type in the array...
- ETypes[i] = NewType;
+ ContainedTys[i] = NewType;
}
StructTypes.finishRefinement(TMI);
@@ -1150,9 +1125,9 @@ void PointerType::refineAbstractType(const DerivedType *OldType,
TypeMap<PointerValType, PointerType>::iterator TMI =
PointerTypes.getEntryForType(this);
- assert(ElementType == OldType);
- ElementType.removeUserFromConcrete();
- ElementType = NewType;
+ assert(ContainedTys[0] == OldType);
+ ContainedTys[0].removeUserFromConcrete();
+ ContainedTys[0] = NewType;
PointerTypes.finishRefinement(TMI);
}