diff options
author | Chris Lattner <sabre@nondot.org> | 2001-10-22 05:56:09 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-10-22 05:56:09 +0000 |
commit | 4a42e909cdff881f6d389f9ec3e0b04b85a73bdd (patch) | |
tree | 9066cb0e8cfca6604141f7bb87724a64fdba2d49 | |
parent | 9245fc75a43a179422f88d7dd2b5b931a0b2972e (diff) |
Fix bug with
%list = type {%list *}
%list = type {%list *}
not being accepted (broken testmisc.ll)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@935 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index e49ffa3a3d..60c966e1eb 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -57,7 +57,8 @@ static struct PerModuleInfo { 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 @@ -80,7 +81,8 @@ static struct PerModuleInfo { 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 @@ -131,7 +133,8 @@ static struct PerMethodInfo { 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() { @@ -226,11 +229,16 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { // 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; } @@ -438,27 +446,41 @@ static bool ResolveType(PATypeHolder<Type> &T) { 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)); } } @@ -1019,6 +1041,17 @@ ConstPool : ConstPool OptAssign CONST ConstVal { 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... |