+ void dump() const { print("dump output"); }
+};
+
+
+// ValTypeBase - This is the base class that is used by the various
+// instantiations of TypeMap. This class is an AbstractType user that notifies
+// the underlying TypeMap when it gets modified.
+//
+template<class ValType, class TypeClass>
+class ValTypeBase : public AbstractTypeUser {
+ TypeMap<ValType, TypeClass> &MyTable;
+protected:
+ inline ValTypeBase(TypeMap<ValType, TypeClass> &tab) : MyTable(tab) {}
+
+ // Subclass should override this... to update self as usual
+ virtual void doRefinement(const DerivedType *OldTy, const Type *NewTy) = 0;
+
+ // typeBecameConcrete - This callback occurs when a contained type refines
+ // to itself, but becomes concrete in the process. Our subclass should remove
+ // itself from the ATU list of the specified type.
+ //
+ virtual void typeBecameConcrete(const DerivedType *Ty) = 0;
+
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
+ assert(OldTy == NewTy || OldTy->isAbstract());
+
+ if (!OldTy->isAbstract())
+ typeBecameConcrete(OldTy);
+
+ TypeMap<ValType, TypeClass> &Table = MyTable; // Copy MyTable reference
+ ValType Tmp(*(ValType*)this); // Copy this.
+ PATypeHandle<TypeClass> OldType(Table.get(*(ValType*)this), this);
+ Table.remove(*(ValType*)this); // Destroy's this!
+
+ // Refine temporary to new state...
+ if (OldTy != NewTy)
+ Tmp.doRefinement(OldTy, NewTy);
+
+ // FIXME: when types are not const!
+ Table.add((ValType&)Tmp, (TypeClass*)OldType.get());
+ }
+
+ void dump() const {
+ cerr << "ValTypeBase instance!\n";
+ }
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Function Type Factory and Value Class...
+//
+
+// FunctionValType - Define a class to hold the key that goes into the TypeMap
+//
+class FunctionValType : public ValTypeBase<FunctionValType, FunctionType> {
+ PATypeHandle<Type> RetTy;
+ vector<PATypeHandle<Type> > ArgTypes;
+ bool isVarArg;
+public:
+ FunctionValType(const Type *ret, const vector<const Type*> &args,
+ bool IVA, TypeMap<FunctionValType, FunctionType> &Tab)
+ : ValTypeBase<FunctionValType, FunctionType>(Tab), RetTy(ret, this),
+ isVarArg(IVA) {
+ for (unsigned i = 0; i < args.size(); ++i)
+ ArgTypes.push_back(PATypeHandle<Type>(args[i], this));
+ }
+
+ // We *MUST* have an explicit copy ctor so that the TypeHandles think that
+ // this FunctionValType owns them, not the old one!
+ //
+ FunctionValType(const FunctionValType &MVT)
+ : ValTypeBase<FunctionValType, FunctionType>(MVT), RetTy(MVT.RetTy, this),
+ isVarArg(MVT.isVarArg) {
+ ArgTypes.reserve(MVT.ArgTypes.size());
+ for (unsigned i = 0; i < MVT.ArgTypes.size(); ++i)
+ ArgTypes.push_back(PATypeHandle<Type>(MVT.ArgTypes[i], this));
+ }
+
+ // Subclass should override this... to update self as usual
+ virtual void doRefinement(const DerivedType *OldType, const Type *NewType) {
+ if (RetTy == OldType) RetTy = NewType;
+ for (unsigned i = 0, e = ArgTypes.size(); i != e; ++i)
+ if (ArgTypes[i] == OldType) ArgTypes[i] = NewType;
+ }
+
+ virtual void typeBecameConcrete(const DerivedType *Ty) {
+ if (RetTy == Ty) RetTy.removeUserFromConcrete();
+
+ for (unsigned i = 0; i < ArgTypes.size(); ++i)
+ if (ArgTypes[i] == Ty) ArgTypes[i].removeUserFromConcrete();
+ }
+
+ inline bool operator<(const FunctionValType &MTV) const {
+ if (RetTy.get() < MTV.RetTy.get()) return true;
+ if (RetTy.get() > MTV.RetTy.get()) return false;
+
+ if (ArgTypes < MTV.ArgTypes) return true;
+ return (ArgTypes == MTV.ArgTypes) && isVarArg < MTV.isVarArg;
+ }
+};
+
+// Define the actual map itself now...
+static TypeMap<FunctionValType, FunctionType> FunctionTypes;
+
+// FunctionType::get - The factory function for the FunctionType class...
+FunctionType *FunctionType::get(const Type *ReturnType,
+ const vector<const Type*> &Params,
+ bool isVarArg) {
+ FunctionValType VT(ReturnType, Params, isVarArg, FunctionTypes);
+ FunctionType *MT = FunctionTypes.get(VT);
+ if (MT) return MT;
+
+ FunctionTypes.add(VT, MT = new FunctionType(ReturnType, Params, isVarArg));
+
+#ifdef DEBUG_MERGE_TYPES
+ cerr << "Derived new type: " << MT << endl;
+#endif
+ return MT;