From e244a2501478c68864a5a9c54718788bdd649b77 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 3 Nov 2001 03:27:53 +0000 Subject: Fix major bugs in type resolution git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1092 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/AbstractTypeUser.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'include/llvm/AbstractTypeUser.h') 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::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::operator=((const TypeSC*)NewTy); } // operator= - Allow assignment to handle -- cgit v1.2.3