Module *CurrentModule;
vector<ValueList> Values; // Module level numbered definitions
vector<ValueList> LateResolveValues;
- vector<PATypeHolder<Type> > Types, LateResolveTypes;
+ vector<PATypeHolder<Type> > Types;
+ map<ValID, PATypeHolder<Type> > LateResolveTypes;
// GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
// references to global values. Global values may be referenced before they
if (!GlobalRefs.empty()) {
// TODO: Make this more detailed! Loop over each undef value and print
// info
- ThrowException("TODO: Make better error - Unresolved forward constant references exist!");
+ ThrowException("TODO: Make better error - Unresolved forward constant "
+ "references exist!");
}
Values.clear(); // Clear out method local definitions
vector<ValueList> Values; // Keep track of numbered definitions
vector<ValueList> LateResolveValues;
- vector<PATypeHolder<Type> > Types, LateResolveTypes;
+ vector<PATypeHolder<Type> > Types;
+ map<ValID, PATypeHolder<Type> > LateResolveTypes;
bool isDeclare; // Is this method a forward declararation?
inline PerMethodInfo() {
//
if (DoNotImprovise) return 0; // Do we just want a null to be returned?
- vector<PATypeHolder<Type> > *LateResolver = inMethodScope() ?
- &CurMeth.LateResolveTypes : &CurModule.LateResolveTypes;
+ map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ?
+ CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
+
+ map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
+ if (I != LateResolver.end()) {
+ return I->second;
+ }
Type *Typ = new TypePlaceHolder(Type::TypeTy, D);
- InsertType(Typ, *LateResolver);
+ LateResolver.insert(make_pair(D, Typ));
return Typ;
}
return false;
}
+// ResolveTypeTo - A brand new type was just declared. This means that (if
+// name is not null) things referencing Name can be resolved. Otherwise, things
+// refering to the number can be resolved. Do this now.
+//
+static void ResolveTypeTo(char *Name, const Type *ToTy) {
+ vector<PATypeHolder<Type> > &Types = inMethodScope ?
+ CurMeth.Types : CurModule.Types;
+
+ ValID D;
+ if (Name) D = ValID::create(Name);
+ else D = ValID::create((int)Types.size());
+
+ map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ?
+ CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
+
+ map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
+ if (I != LateResolver.end()) {
+ cast<DerivedType>(I->second.get())->refineAbstractTypeTo(ToTy);
+ LateResolver.erase(I);
+ }
+}
-// ResolveTypes - This goes through the forward referenced type table and makes
-// sure that all type references are complete. This code is executed after the
-// constant pool of a method or module is completely parsed.
+// ResolveTypes - At this point, all types should be resolved. Any that aren't
+// are errors.
//
-static void ResolveTypes(vector<PATypeHolder<Type> > &LateResolveTypes) {
- while (!LateResolveTypes.empty()) {
- if (ResolveType(LateResolveTypes.back())) {
- const Type *Ty = LateResolveTypes.back();
- ValID &DID = getValIDFromPlaceHolder(Ty);
-
- if (DID.Type == ValID::NameVal)
- ThrowException("Reference to an invalid type: '" +DID.getName() + "'",
- getLineNumFromPlaceHolder(Ty));
- else
- ThrowException("Reference to an invalid type: #" + itostr(DID.Num),
- getLineNumFromPlaceHolder(Ty));
- }
+static void ResolveTypes(map<ValID, PATypeHolder<Type> > &LateResolveTypes) {
+ if (!LateResolveTypes.empty()) {
+ ValID &DID = LateResolveTypes.begin()->first;
- // No need to delete type, refine does that for us.
- LateResolveTypes.pop_back();
+ if (DID.Type == ValID::NameVal)
+ ThrowException("Reference to an invalid type: '" +DID.getName() + "'",
+ getLineNumFromPlaceHolder(Ty));
+ else
+ ThrowException("Reference to an invalid type: #" + itostr(DID.Num),
+ getLineNumFromPlaceHolder(Ty));
}
}
InsertValue($4);
}
| ConstPool OptAssign TYPE TypesV { // Types can be defined in the const pool
+ // Eagerly resolve types. This is not an optimization, this is a
+ // requirement that is due to the fact that we could have this:
+ //
+ // %list = type { %list * }
+ // %list = type { %list * } ; repeated type decl
+ //
+ // If types are not resolved eagerly, then the two types will not be
+ // determined to be the same type!
+ //
+ ResolveTypeTo($2, $4->get());
+
// TODO: FIXME when Type are not const
if (!setValueName(const_cast<Type*>($4->get()), $2)) {
// If this is not a redefinition of a type...