+
+
+ /// refineAbstractType - The callback method invoked when an abstract type is
+ /// resolved to another type. An object must override this method to update
+ /// its internal state to reference NewType instead of OldType.
+ ///
+ virtual void refineAbstractType(const DerivedType *OldTy,
+ const Type *) {
+ LayoutInfoTy::iterator I = LayoutInfo.find(cast<const StructType>(OldTy));
+ assert(I != LayoutInfo.end() && "Using type but not in map?");
+ RemoveEntry(I, true);
+ }
+
+ /// typeBecameConcrete - The other case which AbstractTypeUsers must be aware
+ /// of is when a type makes the transition from being abstract (where it has
+ /// clients on its AbstractTypeUsers list) to concrete (where it does not).
+ /// This method notifies ATU's when this occurs for a type.
+ ///
+ virtual void typeBecameConcrete(const DerivedType *AbsTy) {
+ LayoutInfoTy::iterator I = LayoutInfo.find(cast<const StructType>(AbsTy));
+ assert(I != LayoutInfo.end() && "Using type but not in map?");
+ RemoveEntry(I, true);
+ }
+
+public:
+ virtual ~StructLayoutMap() {
+ // Remove any layouts.
+ for (LayoutInfoTy::iterator
+ I = LayoutInfo.begin(), E = LayoutInfo.end(); I != E; ++I) {
+ const Type *Key = I->first;
+ StructLayout *Value = I->second;
+
+ if (Key->isAbstract())
+ Key->removeAbstractTypeUser(this);
+
+ Value->~StructLayout();
+ free(Value);
+ }
+ }
+
+ void InvalidateEntry(const StructType *Ty) {
+ LayoutInfoTy::iterator I = LayoutInfo.find(Ty);
+ if (I == LayoutInfo.end()) return;
+ RemoveEntry(I, Ty->isAbstract());
+ }
+
+ StructLayout *&operator[](const StructType *STy) {
+ return LayoutInfo[STy];
+ }
+
+ // for debugging...
+ virtual void dump() const {}
+};
+
+} // end anonymous namespace
+
+TargetData::~TargetData() {
+ delete static_cast<StructLayoutMap*>(LayoutMap);