+
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "Type " << (void*)this << " equilivant to existing " << (void*)MTy
+ << " - destroying!\n";
+#endif
+ refineAbstractTypeTo(MTy); // Different type altogether...
+ return;
+ }
+ setDerivedTypeProperties(); // Update the name and isAbstract
+ typeIsRefined();
+}
+
+
+// refineAbstractType - Called when a contained type is found to be more
+// concrete - this could potentially change us from an abstract type to a
+// concrete type.
+//
+void ArrayType::refineAbstractType(const DerivedType *OldType,
+ const Type *NewType) {
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "ArrayTy::refineAbstractTy(" << (void*)OldType << "["
+ << OldType->getDescription() << "], " << (void*)NewType << " ["
+ << NewType->getDescription() << "])\n";
+#endif
+ assert(OldType == ElementType && "Cannot refine from OldType!");
+ ElementType = NewType;
+
+ // Notify everyone that I have changed!
+ if (const ArrayType *ATy = ArrayTypes.containsEquivalent(this)) {
+#ifndef _NDEBUG
+ // Calculate accurate name for debugging purposes
+ vector<const Type *> TypeStack;
+ bool isAbstract = false, isRecursive = false;
+ setDescription(getTypeProps(this, TypeStack, isAbstract, isRecursive));
+#endif
+
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "Type " << (void*)this << " equilivant to existing " << (void*)ATy
+ << " - destroying!\n";
+#endif
+ refineAbstractTypeTo(ATy); // Different type altogether...
+ return;
+ }
+ setDerivedTypeProperties(); // Update the name and isAbstract
+ typeIsRefined(); // Same type, different contents...
+}
+
+
+// refineAbstractType - Called when a contained type is found to be more
+// concrete - this could potentially change us from an abstract type to a
+// concrete type.
+//
+void StructType::refineAbstractType(const DerivedType *OldType,
+ const Type *NewType) {
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "StructTy::refineAbstractTy(" << (void*)OldType << "["
+ << OldType->getDescription() << "], " << (void*)NewType << " ["
+ << NewType->getDescription() << "])\n";
+#endif
+
+ if (OldType != NewType) {
+ unsigned i;
+ for (i = 0; i < ETypes.size(); ++i)
+ if (OldType == ETypes[i]) {
+ ETypes[i] = NewType;
+ break;
+ }
+ assert(i != ETypes.size() && "Did not contain oldtype!");
+ }
+
+ vector<const Type *> ElTypes(
+ map_iterator(ETypes.begin(), mem_fun_ref(&PATypeHandle<Type>::get)),
+ map_iterator(ETypes.end() , mem_fun_ref(&PATypeHandle<Type>::get)));
+
+
+ // Notify everyone that I have changed!
+ if (const StructType *STy = StructTypes.containsEquivalent(this)) {
+#ifndef _NDEBUG
+ // Calculate accurate name for debugging purposes
+ vector<const Type *> TypeStack;
+ bool isAbstract = false, isRecursive = false;
+ setDescription(getTypeProps(this, TypeStack, isAbstract, isRecursive));
+#endif
+
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "Type " << (void*)this << " equilivant to existing " << (void*)STy
+ << " - destroying!\n";
+#endif
+ refineAbstractTypeTo(STy); // Different type altogether...
+ return;
+ }
+ setDerivedTypeProperties(); // Update the name and isAbstract
+ typeIsRefined(); // Same type, different contents...
+}
+
+// refineAbstractType - Called when a contained type is found to be more
+// concrete - this could potentially change us from an abstract type to a
+// concrete type.
+//
+void PointerType::refineAbstractType(const DerivedType *OldType,
+ const Type *NewType) {
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "PointerTy::refineAbstractTy(" << (void*)OldType << "["
+ << OldType->getDescription() << "], " << (void*)NewType << " ["
+ << NewType->getDescription() << "])\n";
+#endif
+ assert(OldType == ValueType && "Cannot refine from OldType!");
+ ValueType = NewType;
+
+ // Notify everyone that I have changed!
+ if (const PointerType *PTy = PointerTypes.containsEquivalent(this)) {
+#ifndef _NDEBUG
+ // Calculate accurate name for debugging purposes
+ vector<const Type *> TypeStack;
+ bool isAbstract = false, isRecursive = false;
+ setDescription(getTypeProps(this, TypeStack, isAbstract, isRecursive));
+#endif
+
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "Type " << (void*)this << " equilivant to existing " << (void*)PTy
+ << " - destroying!\n";
+#endif
+ refineAbstractTypeTo(PTy); // Different type altogether...
+ return;
+ }
+ setDerivedTypeProperties(); // Update the name and isAbstract
+ typeIsRefined(); // Same type, different contents...