summaryrefslogtreecommitdiff
path: root/include/llvm
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 /include/llvm
parent2d3e8bba628843bf2dffa21f69d9b45098d3bfc4 (diff)
downloadllvm-e244a2501478c68864a5a9c54718788bdd649b77.tar.gz
llvm-e244a2501478c68864a5a9c54718788bdd649b77.tar.bz2
llvm-e244a2501478c68864a5a9c54718788bdd649b77.tar.xz
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 'include/llvm')
-rw-r--r--include/llvm/AbstractTypeUser.h26
-rw-r--r--include/llvm/DerivedTypes.h8
2 files changed, 31 insertions, 3 deletions
diff --git a/include/llvm/AbstractTypeUser.h b/include/llvm/AbstractTypeUser.h
index 24c061a3bb..a36bd49e23 100644
--- a/include/llvm/AbstractTypeUser.h
+++ b/include/llvm/AbstractTypeUser.h
@@ -35,6 +35,16 @@ public:
// after this method is invoked, OldType shall be deleted, so referencing it
// is quite unwise.
//
+ // Another case that is important to consider is when a type is refined, but
+ // stays in the same place in memory. In this case OldTy will equal NewTy.
+ // This callback just notifies ATU's that the underlying structure of the type
+ // has changed... but any previously used properties are still valid.
+ //
+ // Note that it is possible to refine a type with parameters OldTy==NewTy, and
+ // OldTy is no longer abstract. In this case, abstract type users should
+ // release their hold on a type, because it went from being abstract to
+ // concrete.
+ //
virtual void refineAbstractType(const DerivedType *OldTy,
const Type *NewTy) = 0;
};
@@ -94,6 +104,14 @@ public:
// operator-> - Allow user to dereference handle naturally...
inline const TypeSubClass *operator->() const { return Ty; }
+
+ // removeUserFromConcrete - This function should be called when the User is
+ // notified that our type is refined... and the type is being refined to
+ // itself, which is now a concrete type. When a type becomes concrete like
+ // this, we MUST remove ourself from the AbstractTypeUser list, even though
+ // the type is apparently concrete.
+ //
+ inline void removeUserFromConcrete();
};
@@ -113,7 +131,13 @@ public:
//
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
assert(get() == OldTy && "Can't refine to unknown value!");
- PATypeHandle<TypeSC>::operator=((const TypeSC*)NewTy);
+
+ // Check to see if the type just became concrete. If so, we have to
+ // removeUser to get off its AbstractTypeUser list
+ removeUserFromConcrete();
+
+ if (OldTy != NewTy)
+ PATypeHandle<TypeSC>::operator=((const TypeSC*)NewTy);
}
// operator= - Allow assignment to handle
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index fdc654d7fc..8c6b4a533b 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -160,7 +160,6 @@ protected:
// Private ctor - Only can be created by a static member...
ArrayType(const Type *ElType, int NumEl);
-
public:
inline const Type *getElementType() const { return ElementType; }
@@ -252,7 +251,6 @@ protected:
// Private ctor - Only can be created by a static member...
PointerType(const Type *ElType);
-
public:
inline const Type *getValueType() const { return ValueType; }
@@ -326,4 +324,10 @@ template <class TypeSubClass> void PATypeHandle<TypeSubClass>::removeUser() {
cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
}
+template <class TypeSubClass>
+void PATypeHandle<TypeSubClass>::removeUserFromConcrete() {
+ if (!Ty->isAbstract())
+ cast<DerivedType>(Ty)->removeAbstractTypeUser(User);
+}
+
#endif