summaryrefslogtreecommitdiff
path: root/include/llvm/AbstractTypeUser.h
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/AbstractTypeUser.h
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/AbstractTypeUser.h')
-rw-r--r--include/llvm/AbstractTypeUser.h26
1 files changed, 25 insertions, 1 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