aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore/Type.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-11-03 03:27:53 +0000
committerChris Lattner <sabre@nondot.org>2001-11-03 03:27:53 +0000
commite244a2501478c68864a5a9c54718788bdd649b77 (patch)
tree47c538b334d24b0d496385c665e3c40f2dc8eeaa /lib/VMCore/Type.cpp
parent2d3e8bba628843bf2dffa21f69d9b45098d3bfc4 (diff)
downloadexternal_llvm-e244a2501478c68864a5a9c54718788bdd649b77.zip
external_llvm-e244a2501478c68864a5a9c54718788bdd649b77.tar.gz
external_llvm-e244a2501478c68864a5a9c54718788bdd649b77.tar.bz2
Fix major bugs in type resolution
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1092 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Type.cpp')
-rw-r--r--lib/VMCore/Type.cpp113
1 files changed, 101 insertions, 12 deletions
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index ba3f5e0..29d80fc 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -151,6 +151,11 @@ ArrayType::ArrayType(const Type *ElType, int NumEl)
NumElements = NumEl;
setDerivedTypeProperties();
}
+ArrayType::~ArrayType() {
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "Destroyed type: " << getDescription() << endl;
+#endif
+}
StructType::StructType(const vector<const Type*> &Types)
: DerivedType("", StructTyID) {
@@ -166,6 +171,11 @@ PointerType::PointerType(const Type *E) : DerivedType("", PointerTyID),
ValueType(PATypeHandle<Type>(E, this)) {
setDerivedTypeProperties();
}
+PointerType::~PointerType() {
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "Destoyed type: " << getDescription() << endl;
+#endif
+}
OpaqueType::OpaqueType() : DerivedType("", OpaqueTyID) {
setAbstract(true);
@@ -381,7 +391,16 @@ public:
// corrected.
//
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
- if (OldTy == NewTy) return;
+ if (OldTy == NewTy) {
+ if (!OldTy->isAbstract()) {
+ // Check to see if the type just became concrete.
+ // If so, remove self from user list.
+ for (MapTy::iterator I = Map.begin(), E = Map.end(); I != E; ++I)
+ if (I->second == OldTy)
+ I->second.removeUserFromConcrete();
+ }
+ return;
+ }
#ifdef DEBUG_MERGE_TYPES
cerr << "Removing Old type from Tab: " << (void*)OldTy << ", "
<< OldTy->getDescription() << " replacement == " << (void*)NewTy
@@ -426,9 +445,19 @@ protected:
// Subclass should override this... to update self as usual
virtual void doRefinement(const DerivedType *OldTy, const Type *NewTy) = 0;
+
+ // typeBecameConcrete - This callback occurs when a contained type refines
+ // to itself, but becomes concrete in the process. Our subclass should remove
+ // itself from the ATU list of the specified type.
+ //
+ virtual void typeBecameConcrete(const DerivedType *Ty) = 0;
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
- if (OldTy == NewTy) return;
+ if (OldTy == NewTy) {
+ if (!OldTy->isAbstract())
+ typeBecameConcrete(OldTy);
+ return;
+ }
TypeMap<ValType, TypeClass> &Table = MyTable; // Copy MyTable reference
ValType Tmp(*(ValType*)this); // Copy this.
PATypeHandle<TypeClass> OldType(Table.get(*(ValType*)this), this);
@@ -481,6 +510,13 @@ public:
if (ArgTypes[i] == OldType) ArgTypes[i] = NewType;
}
+ virtual void typeBecameConcrete(const DerivedType *Ty) {
+ if (RetTy == Ty) RetTy.removeUserFromConcrete();
+
+ for (unsigned i = 0; i < ArgTypes.size(); ++i)
+ if (ArgTypes[i] == Ty) ArgTypes[i].removeUserFromConcrete();
+ }
+
inline bool operator<(const MethodValType &MTV) const {
if (RetTy.get() < MTV.RetTy.get()) return true;
if (RetTy.get() > MTV.RetTy.get()) return false;
@@ -531,6 +567,12 @@ public:
if (ValTy == OldType) ValTy = NewType;
}
+ virtual void typeBecameConcrete(const DerivedType *Ty) {
+ assert(ValTy == Ty &&
+ "Contained type became concrete but we're not using it!");
+ ValTy.removeUserFromConcrete();
+ }
+
inline bool operator<(const ArrayValType &MTV) const {
if (Size < MTV.Size) return true;
return Size == MTV.Size && ValTy.get() < MTV.ValTy.get();
@@ -587,6 +629,11 @@ public:
if (ElTypes[i] == OldType) ElTypes[i] = NewType;
}
+ virtual void typeBecameConcrete(const DerivedType *Ty) {
+ for (unsigned i = 0; i < ElTypes.size(); ++i)
+ if (ElTypes[i] == Ty) ElTypes[i].removeUserFromConcrete();
+ }
+
inline bool operator<(const StructValType &STV) const {
return ElTypes < STV.ElTypes;
}
@@ -631,6 +678,12 @@ public:
if (ValTy == OldType) ValTy = NewType;
}
+ virtual void typeBecameConcrete(const DerivedType *Ty) {
+ assert(ValTy == Ty &&
+ "Contained type became concrete but we're not using it!");
+ ValTy.removeUserFromConcrete();
+ }
+
inline bool operator<(const PointerValType &MTV) const {
return ValTy.get() < MTV.ValTy.get();
}
@@ -675,22 +728,20 @@ void DerivedType::removeAbstractTypeUser(AbstractTypeUser *U) const {
AbstractTypeUsers.erase(AbstractTypeUsers.begin()+i-1);
#ifdef DEBUG_MERGE_TYPES
- cerr << " removeAbstractTypeUser[" << (void*)this << ", "
- << getDescription() << "][" << AbstractTypeUsers.size()
- << "] User = " << U << endl;
+ cerr << " removeAbstractTypeUser<" << (void*)this << ", "
+ << getDescription() << ">[" << i << "] User = " << U << endl;
#endif
- if (AbstractTypeUsers.empty()) {
+ if (AbstractTypeUsers.empty() && isAbstract()) {
#ifdef DEBUG_MERGE_TYPES
- cerr << "DELETEing unused abstract type: " << getDescription()
- << "[" << (void*)this << "]" << endl;
+ cerr << "DELETEing unused abstract type: <" << getDescription()
+ << ">[" << (void*)this << "]" << endl;
#endif
delete this; // No users of this abstract type!
}
return;
}
}
- assert(isAbstract() && "removeAbstractTypeUser: Type not abstract!");
assert(0 && "AbstractTypeUser not in user list!");
}
@@ -746,6 +797,9 @@ void DerivedType::refineAbstractTypeTo(const Type *NewType) {
#endif
User->refineAbstractType(this, NewTy);
+ if (AbstractTypeUsers.size() == OldSize) {
+ User->refineAbstractType(this, NewTy);
+ }
assert(AbstractTypeUsers.size() != OldSize &&
"AbsTyUser did not remove self from user list!");
}
@@ -786,6 +840,19 @@ void DerivedType::typeIsRefined() {
}
--isRefining;
+
+#ifndef _NDEBUG
+ if (!(isAbstract() || AbstractTypeUsers.empty()))
+ for (unsigned i = 0; i < AbstractTypeUsers.size(); ++i) {
+ if (AbstractTypeUsers[i] != this) {
+ // Debugging hook
+ cerr << "FOUND FAILURE\n";
+ AbstractTypeUsers[i]->refineAbstractType(this, this);
+ assert(0 && "Type became concrete,"
+ " but it still has abstract type users hanging around!");
+ }
+ }
+#endif
}
@@ -803,6 +870,12 @@ void MethodType::refineAbstractType(const DerivedType *OldType,
<< NewType->getDescription() << "])\n";
#endif
+ if (!OldType->isAbstract()) {
+ if (ResultType == OldType) ResultType.removeUserFromConcrete();
+ for (unsigned i = 0; i < ParamTys.size(); ++i)
+ if (ParamTys[i] == OldType) ParamTys[i].removeUserFromConcrete();
+ }
+
if (OldType != NewType) {
if (ResultType == OldType) ResultType = NewType;
@@ -812,10 +885,10 @@ void MethodType::refineAbstractType(const DerivedType *OldType,
const MethodType *MT = MethodTypes.containsEquivalent(this);
if (MT && MT != this) {
- refineAbstractTypeTo(MT); // Different type altogether...
+ refineAbstractTypeTo(MT); // Different type altogether...
} else {
setDerivedTypeProperties(); // Update the name and isAbstract
- typeIsRefined(); // Same type, different contents...
+ typeIsRefined(); // Same type, different contents...
}
}
@@ -832,6 +905,11 @@ void ArrayType::refineAbstractType(const DerivedType *OldType,
<< NewType->getDescription() << "])\n";
#endif
+ if (!OldType->isAbstract()) {
+ assert(ElementType == OldType);
+ ElementType.removeUserFromConcrete();
+ }
+
ElementType = NewType;
const ArrayType *AT = ArrayTypes.containsEquivalent(this);
if (AT && AT != this) {
@@ -854,12 +932,18 @@ void StructType::refineAbstractType(const DerivedType *OldType,
<< OldType->getDescription() << "], " << (void*)NewType << " ["
<< NewType->getDescription() << "])\n";
#endif
+ if (!OldType->isAbstract()) {
+ for (unsigned i = 0; i < ETypes.size(); ++i)
+ if (ETypes[i] == OldType)
+ ETypes[i].removeUserFromConcrete();
+ }
+
if (OldType != NewType) {
// Update old type to new type in the array...
for (unsigned i = 0; i < ETypes.size(); ++i)
if (ETypes[i] == OldType)
ETypes[i] = NewType;
- }
+ }
const StructType *ST = StructTypes.containsEquivalent(this);
if (ST && ST != this) {
@@ -882,6 +966,11 @@ void PointerType::refineAbstractType(const DerivedType *OldType,
<< NewType->getDescription() << "])\n";
#endif
+ if (!OldType->isAbstract()) {
+ assert(ValueType == OldType);
+ ValueType.removeUserFromConcrete();
+ }
+
ValueType = NewType;
const PointerType *PT = PointerTypes.containsEquivalent(this);