public virtual void CaseAPointerLvalue(APointerLvalue node) { DefaultCase(node); }
public override void CaseAPointerLvalue(APointerLvalue node) { InAPointerLvalue(node); if (node.GetBase() != null) { node.GetBase().Apply(this); } if (node.GetTokens() != null) { node.GetTokens().Apply(this); } OutAPointerLvalue(node); }
public override void CaseAPointerLvalue(APointerLvalue node) { IsConst = false; }
public override void OutAPointerMultiLvalue(APointerMultiLvalue node) { ALvalueExp lvalueExp; APointerLvalue pointerLvalue = new APointerLvalue((TStar) node.GetTokens()[0], node.GetBase()); while (node.GetTokens().Count > 0) { lvalueExp = new ALvalueExp(pointerLvalue); pointerLvalue = new APointerLvalue((TStar) node.GetTokens()[0], lvalueExp); } node.ReplaceBy(pointerLvalue); pointerLvalue.Apply(this); }
public override void OutAArrayLvalue(AArrayLvalue node) { PType type = data.ExpTypes[node.GetBase()]; PType argType = data.ExpTypes[node.GetIndex()]; List<APropertyDecl> matchingArrayProperties = new List<APropertyDecl>(); List<APropertyDecl> implicitStructArrayProperties = new List<APropertyDecl>(); if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)type)) { AStructDecl structDecl = data.StructTypeLinks[(ANamedType) type]; foreach (APropertyDecl property in data.StructProperties[structDecl]) { if (property.GetName().Text == "") { PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType(); if (Assignable(argType, proprtyArgType)) matchingArrayProperties.Add(property); } } } if (type is APointerType) { APointerType aType = (APointerType)type; PType baseType = aType.GetType(); if (baseType is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)baseType)) { AStructDecl structDecl = data.StructTypeLinks[(ANamedType)baseType]; foreach (APropertyDecl property in data.StructProperties[structDecl]) { if (property.GetName().Text == "") { PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType(); if (Assignable(argType, proprtyArgType)) implicitStructArrayProperties.Add(property); } } } } List<IList> visibleDecls = Util.GetVisibleDecls(node, true); foreach (IList declList in visibleDecls) { foreach (PDecl decl in declList) { if (decl is AEnrichmentDecl) { AEnrichmentDecl enrichment = (AEnrichmentDecl)decl; if (Util.TypesEqual(type, enrichment.GetType(), data)) { foreach (PDecl enrichmentDecl in enrichment.GetDecl()) { if (enrichmentDecl is APropertyDecl) { APropertyDecl property = (APropertyDecl) enrichmentDecl; if (property.GetName().Text == "") { PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType(); if (Assignable(argType, proprtyArgType)) matchingArrayProperties.Add(property); } } } } } } } bool matchesNormalArray = false; ALvalueExp replaceBaseExp = null; if (Assignable(argType, new ANamedType(new TIdentifier("int"), null))) { if (type is AArrayTempType) { AArrayTempType aType = (AArrayTempType) type; type = aType.GetType(); matchesNormalArray = true; } else if (type is ADynamicArrayType) { ADynamicArrayType aType = (ADynamicArrayType) type; type = aType.GetType(); matchesNormalArray = true; } else if (type is APointerType) { //Implicit conversion for a[] to (*a)[] APointerType aType = (APointerType) type; if (aType.GetType() is AArrayTempType || aType.GetType() is ADynamicArrayType) { APointerLvalue pointer = new APointerLvalue(new TStar("*"), node.GetBase()); replaceBaseExp = new ALvalueExp(pointer); matchesNormalArray = true; } } } if (matchingArrayProperties.Count == 0 && !matchesNormalArray && implicitStructArrayProperties.Count == 0) errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText72"))); if (matchingArrayProperties.Count + (matchesNormalArray ? 1 : 0) > 1) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (APropertyDecl property in matchingArrayProperties) { subErrors.Add(new ErrorCollection.Error(property.GetName(), LocRM.GetString("ErrorText62"))); } if (matchesNormalArray) subErrors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText74"))); errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText73"), false, subErrors.ToArray())); throw new ParserException(node.GetToken(), "TypeChecking.OutAArrayLvalue"); } if (matchingArrayProperties.Count + (matchesNormalArray ? 1 : 0) == 0 && implicitStructArrayProperties.Count > 1) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (APropertyDecl property in implicitStructArrayProperties) { subErrors.Add(new ErrorCollection.Error(property.GetName(), LocRM.GetString("ErrorText62"))); } errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText73"), false, subErrors.ToArray())); throw new ParserException(node.GetToken(), "TypeChecking.OutAArrayLvalue"); } if (matchingArrayProperties.Count == 1) { APropertyDecl property = matchingArrayProperties[0]; type = property.GetType(); data.ArrayPropertyLinks[node] = new Util.Pair<APropertyDecl, bool>(property, false); CheckPropertyAccessibility(property, node.Parent() is AAssignmentExp, node.GetToken()); } else if (implicitStructArrayProperties.Count == 1) { APropertyDecl property = implicitStructArrayProperties[0]; type = property.GetType(); data.ArrayPropertyLinks[node] = new Util.Pair<APropertyDecl, bool>(property, true); CheckPropertyAccessibility(property, node.Parent() is AAssignmentExp, node.GetToken()); } if (replaceBaseExp == null) data.LvalueTypes[node] = type; else { node.SetBase(replaceBaseExp); //pointer.Apply(this); OutAPointerLvalue((APointerLvalue)replaceBaseExp.GetLvalue()); OutALvalueExp(replaceBaseExp); OutAArrayLvalue(node); } //if (!Assignable(data.ExpTypes[node.GetIndex()], new ANamedType(new TIdentifier("int"), null))) // errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, "Indexes of arrays must be of integer type.")); }
public override void OutAPointerLvalue(APointerLvalue node) { PType type = data.ExpTypes[node.GetBase()]; if (!(type is APointerType)) { errors.Add(new ErrorCollection.Error(node.GetTokens(), currentSourceFile, LocRM.GetString("ErrorText149"))); data.LvalueTypes[node] = type; } else { data.LvalueTypes[node] = ((APointerType) type).GetType(); } base.OutAPointerLvalue(node); }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { AMethodDecl decl = finalTrans.data.SimpleMethodLinks[node]; if (structMethods.Contains(decl)) {//The target is a struct method that has been moved out if (node.GetArgs().Count < decl.GetFormals().Count && Util.HasAncestor<AStructDecl>(node)) {//If this is the case, we Must be inside the same struct as the target. - Not with enheritance ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName")); ALvalueExp exp = new ALvalueExp(local); finalTrans.data.LvalueTypes[local] = finalTrans.data.ExpTypes[exp] = structFormal.GetType(); finalTrans.data.LocalLinks[local] = structFormal; //If we're calling from class to struct, we must depointer it AStructDecl currentStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(Util.GetAncestor<AMethodDecl>(node))).Key; AStructDecl baseStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(decl)).Key; if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class { APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp); exp = new ALvalueExp(pointerLvalue); finalTrans.data.LvalueTypes[pointerLvalue] = finalTrans.data.ExpTypes[exp] = ((APointerType)structFormal.GetType()).GetType(); } node.GetArgs().Add(exp); } } else if (Util.GetAncestor<AStructDecl>(decl) != null && OldParentStruct.ContainsKey(Util.GetAncestor<AMethodDecl>(node))) {//The target is a struct method that hasn't been moved out if (Util.GetAncestor<AStructDecl>(decl) == OldParentStruct[Util.GetAncestor<AMethodDecl>(node)] && decl.GetStatic() == null) {//We have an internal struct call. Expect to have one too many args if (node.GetArgs().Count == decl.GetFormals().Count) { ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName")); ALvalueExp exp = new ALvalueExp(local); finalTrans.data.LvalueTypes[local] = finalTrans.data.ExpTypes[exp] = structFormal.GetType(); finalTrans.data.LocalLinks[local] = structFormal; //If we're calling from class to struct, we must depointer it AStructDecl currentStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(Util.GetAncestor<AMethodDecl>(node))).Key; AStructDecl baseStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(decl)).Key; if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class { APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp); exp = new ALvalueExp(pointerLvalue); finalTrans.data.LvalueTypes[pointerLvalue] = finalTrans.data.ExpTypes[exp] = ((APointerType)structFormal.GetType()).GetType(); } node.GetArgs().Add(exp); } } } base.CaseASimpleInvokeExp(node); }
public override void CaseAPointerLvalue(APointerLvalue node) { //Build the list currentPointer.Clear(); base.CaseAPointerLvalue(node); //Todo: insert runtime check here //if (currentPointer.Count == 0 || !setPointers.Contains(MakePointer(currentPointer))) if (!isSet) { PStm pStm = Util.GetAncestor<PStm>(node); if (pStm != null) { AABlock pBlock = (AABlock) pStm.Parent(); /* * if (<pointer> == null) * { * UIDisplayMessage(PlayerGroupAll, messageAreaDebug, StringToText(<filename>[<lineNr>:<pos>] + " null pointer exception")); * int i = 1 / 0; * } */ AASourceFile currentSourceFile = Util.GetAncestor<AASourceFile>(node); node.GetBase().Apply(new MoveMethodDeclsOut("pointerVar", data)); PExp pointer = Util.MakeClone(node.GetBase(), data); ABinopExp cond = new ABinopExp(pointer, new AEqBinop(new TEq("==")), new ANullExp()); AABlock ifBlock = new AABlock(); ASimpleInvokeExp playerGroupAllInvoke = new ASimpleInvokeExp(new TIdentifier("PlayerGroupAll"), new ArrayList()); AFieldLvalue messageAreaDebugLink = new AFieldLvalue(new TIdentifier("c_messageAreaDebug")); ALvalueExp messageAreaDebugLinkExp = new ALvalueExp(messageAreaDebugLink); ASimpleInvokeExp stringToTextInvoke = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList() { new AStringConstExp( new TStringLiteral("\"" + currentSourceFile . GetName () . Text + "[" + node. GetTokens () . Line + "," + node. GetTokens () . Pos + "]: Null pointer exception\"")) }); ASimpleInvokeExp displayMessageInvoke = new ASimpleInvokeExp( new TIdentifier("UIDisplayMessage"), new ArrayList() {playerGroupAllInvoke, messageAreaDebugLinkExp, stringToTextInvoke}); ifBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), displayMessageInvoke)); ABinopExp iDeclInit = new ABinopExp(new AIntConstExp(new TIntegerLiteral("1")), new ADivideBinop(new TDiv("/")), new AIntConstExp(new TIntegerLiteral("0"))); AALocalDecl iDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("int"), null), new TIdentifier("i"), iDeclInit); ifBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), iDecl)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new AIfThenStm(new TLParen("("), cond, new ABlockStm(new TLBrace("{"), ifBlock))); data.Locals[ifBlock] = new List<AALocalDecl>(){iDecl}; data.ExpTypes[cond.GetRight()] = new ANullType(); data.ExpTypes[cond] = new ANamedType(new TIdentifier("bool"), null); data.ExpTypes[playerGroupAllInvoke] = new ANamedType(new TIdentifier("playergroup"), null); data.ExpTypes[messageAreaDebugLinkExp] = data.LvalueTypes[messageAreaDebugLink] = data.ExpTypes[iDeclInit] = data.ExpTypes[iDeclInit.GetLeft()] = data.ExpTypes[iDeclInit.GetRight()] = new ANamedType(new TIdentifier("int"), null); data.ExpTypes[stringToTextInvoke] = new ANamedType(new TIdentifier("text"), null); data.ExpTypes[(PExp) stringToTextInvoke.GetArgs()[0]] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[displayMessageInvoke] = new AVoidType(new TVoid("void")); data.SimpleMethodLinks[playerGroupAllInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == playerGroupAllInvoke.GetName().Text); data.SimpleMethodLinks[displayMessageInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == displayMessageInvoke.GetName().Text); data.SimpleMethodLinks[stringToTextInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == stringToTextInvoke.GetName().Text); data.FieldLinks[messageAreaDebugLink] = data.Libraries.Fields.Find(f => f.GetName().Text == messageAreaDebugLink.GetName().Text); if (currentPointer.Count > 0) { setPointers.Add(MakePointer(currentPointer)); } } } currentPointer.Add(new PointerPointer()); currentPointer = MakePointer(currentPointer); isSet = Contains(setPointers, currentPointer); isExposed = Contains(exposedPointers, currentPointer); //If the currentPointer is in null pointers, report error.. and then again - we might not reach this statement - warning, and runtime check //If the currentPointer is not in setPointers, insert runtime check }
private AALocalDecl TurnDynamic(PExp exp, AALocalDecl targetDecl, PType type, bool assignBefore = true, bool assignAfter = false, bool makeDelete = true) { exp.Apply(mover); //insert //<basetype>[]* bulkCopyVar = new <baseType>[<dim>](); //bulkCopyVar[0] = arg[0]; //bulkCopyVar[1] = arg[1]; //bulkCopyVar[2] = arg[2]; //... //Invoke(..., bulkCopyVar, ...); //If we need to clean up after, move the exp to it's own statement. AALocalDecl newLocal; if (type is AArrayTempType) { AArrayTempType aType = (AArrayTempType) type; ANewExp newExp = new ANewExp(new TNew("new"), new AArrayTempType( new TLBracket("["), Util.MakeClone(aType.GetType(), data), Util.MakeClone(aType.GetDimention(), data), (TIntegerLiteral) aType.GetIntDim().Clone()), new ArrayList()); newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), new ADynamicArrayType( new TLBracket("["), Util.MakeClone(aType.GetType(), data))), new TIdentifier("bulkCopyVar"), newExp ); } else { ANewExp newExp = new ANewExp(new TNew("new"), Util.MakeClone(type, data), new ArrayList()); newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), Util.MakeClone(type, data)), new TIdentifier("bulkCopyVar"), newExp ); } PStm pStm = Util.GetAncestor<PStm>(exp); AABlock pBlock = (AABlock) pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), newLocal)); PLvalue bulkCopyRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); data.LocalLinks[(ALocalLvalue) bulkCopyRef] = newLocal; data.LvalueTypes[bulkCopyRef] = newLocal.GetType(); ALvalueExp bulkCopyRefExp; //if (!(type is AArrayTempType)) { bulkCopyRefExp = new ALvalueExp(bulkCopyRef); bulkCopyRef = new APointerLvalue(new TStar("*"), bulkCopyRefExp); data.ExpTypes[bulkCopyRefExp] = newLocal.GetType(); data.LvalueTypes[bulkCopyRef] = type; } if (assignBefore) { List<PStm> stms = MakeAssignments(bulkCopyRef, exp, new List<AALocalDecl>() {targetDecl}); foreach (PStm stm in stms) { pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), stm); } } int addStms = 1; if (assignAfter) { bulkCopyRefExp = new ALvalueExp(bulkCopyRef); data.ExpTypes[bulkCopyRefExp] = data.LvalueTypes[bulkCopyRef]; List<PStm> stms = MakeAssignments(((ALvalueExp)exp).GetLvalue(), bulkCopyRefExp, new List<AALocalDecl>() {targetDecl}); addStms += stms.Count; foreach (PStm stm in stms) { pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, stm); } } bulkCopyRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); bulkCopyRefExp = new ALvalueExp(bulkCopyRef); data.LocalLinks[(ALocalLvalue) bulkCopyRef] = newLocal; data.LvalueTypes[bulkCopyRef] = data.ExpTypes[bulkCopyRefExp] = newLocal.GetType(); exp.ReplaceBy(bulkCopyRefExp); /*if (formal.GetRef() != null || formal.GetOut() != null) { //Get args back }*/ //Delete object if (makeDelete) { bulkCopyRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); bulkCopyRefExp = new ALvalueExp(bulkCopyRef); data.LocalLinks[(ALocalLvalue) bulkCopyRef] = newLocal; data.LvalueTypes[bulkCopyRef] = data.ExpTypes[bulkCopyRefExp] = newLocal.GetType(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + addStms, new ADeleteStm(new TDelete("delete"), bulkCopyRefExp)); } return newLocal; }
public override void OutAStructDecl(AStructDecl node) { //Insert init in each constructor AThisLvalue thisLvalue = new AThisLvalue(new TThis("this")); ALvalueExp thisExp = new ALvalueExp(thisLvalue); APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), thisExp); ANamedType namedType = new ANamedType(new TIdentifier(node.GetName().Text), null); data.StructTypeLinks[namedType] = node; data.LvalueTypes[thisLvalue] = data.ExpTypes[thisExp] = new APointerType(new TStar("*"), namedType); data.LvalueTypes[pointerLvalue] = namedType; foreach (AConstructorDecl constructor in node.GetLocals().OfType<ADeclLocalDecl>().Select(decl => decl.GetDecl()).OfType<AConstructorDecl>()) { AABlock block = new AABlock(new ArrayList(), new TRBrace("}")); MakeAssignments(block, namedType, pointerLvalue, false); ((AABlock)constructor.GetBlock()).GetStatements().Insert(0, new ABlockStm(new TLBrace("{"), block)); } base.OutAStructDecl(node); }
public override void CaseAPointerLvalue(APointerLvalue node) { hadPointer = false; nameExp = null; base.CaseAPointerLvalue(node); if (Util.IsIntPointer(node, data.LvalueTypes[node], data)) { if (nameExp != null) { //Create a data table get string exp nameExp = CreateDynaicGetStm("int"); } else { nameExp = node.GetBase(); } //Replace by str_Array[<base>]; //If this is a compared pointer, replace it by str_Array[<base> >> <<bitsLeft>>] GlobalStructVars vars; int allocateLimit; if (data.EnrichmentTypeLinks.ContainsKey(data.LvalueTypes[node])) { AEnrichmentDecl enrichmentDecl = data.EnrichmentTypeLinks[data.LvalueTypes[node]]; vars = CreateEnrichmentFields(node, enrichmentDecl, data); allocateLimit = int.Parse(enrichmentDecl.GetIntDim().Text); } else { AStructDecl structDecl = data.StructTypeLinks[(ANamedType)data.LvalueTypes[node]]; vars = CreateStructFields(node, structDecl, data); allocateLimit = int.Parse(structDecl.GetIntDim().Text); } AFieldLvalue array = new AFieldLvalue(new TIdentifier(vars.Array.GetName().Text)); ALvalueExp arrayExp = new ALvalueExp(array); PExp arrayIndex = nameExp; if (vars.IdentifierArray != null) { int usedBits = allocateLimit == 0 ? 0 : ((int)Math.Floor(Math.Log(allocateLimit, 2)) + 1); int bitsLeft = 31 - usedBits; int biggestIdentifier = (1 << (bitsLeft + 1)) - 1; AIntConstExp bitsLeftConst = new AIntConstExp(new TIntegerLiteral(bitsLeft.ToString())); arrayIndex = new ABinopExp(arrayIndex, new ARBitShiftBinop(new TRBitShift(">>")), bitsLeftConst); data.ExpTypes[bitsLeftConst] = data.ExpTypes[arrayIndex] = new ANamedType(new TIdentifier("int"), null); } AArrayLvalue replacer = new AArrayLvalue(new TLBracket("["), arrayExp, arrayIndex); node.ReplaceBy(replacer); data.FieldLinks[array] = vars.Array; data.LvalueTypes[array] = data.ExpTypes[arrayExp] = vars.Array.GetType(); data.LvalueTypes[replacer] = ((AArrayTempType) vars.Array.GetType()).GetType(); hadPointer = false; nameExp = null; return; } //if (Util.GetAncestor<AAssignmentExp>(node) != null || Util.GetAncestor<APArrayLengthLvalue>(node) != null) { if (nameExp != null) { //Create a data table get string exp nameExp = CreateDynaicGetStm("string"); } else { nameExp = node.GetBase(); } } hadPointer = true; CheckDynamicLvalue(node); //Todo: Insert runtime check that the pointer is actually not null / points to a delete object //(unless the same pointer was checked before, and it has not been assigned to since, and there has not been a method call since. }
public override void OutASimpleInvokeExp(ASimpleInvokeExp node) { if (data.BulkCopyProcessedInvokes.Contains(node)) { base.OutASimpleInvokeExp(node); return; } //If anything needs to be put after the invoke, move it to it's own local decl or exp statement AMethodDecl method = data.SimpleMethodLinks[node]; if (!processedMethods.Contains(method)) CaseAMethodDecl(method); bool moveOut = Util.IsBulkCopy(data.ExpTypes[node]); PType type; if (!moveOut) for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp)node.GetArgs()[i]; AALocalDecl formal = (AALocalDecl)method.GetFormals()[i]; type = data.ExpTypes[arg]; if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null) { moveOut = true; break; } } if (moveOut && !(node.Parent() is AExpStm || node.Parent() is AALocalDecl)) { PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock) pStm.Parent(); //Can not be a void type, since it is not in an expStm AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node], data), new TIdentifier("bulkCopyVar"), null); ALocalLvalue bulkCopyVarRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); ALvalueExp bulkCopyVarRefExp = new ALvalueExp(bulkCopyVarRef); node.ReplaceBy(bulkCopyVarRefExp); localDecl.SetInit(node); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl)); data.LocalLinks[bulkCopyVarRef] = localDecl; data.LvalueTypes[bulkCopyVarRef] = data.ExpTypes[bulkCopyVarRefExp] = localDecl.GetType(); } //Replace bulk copy arguments with a new pointer for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp) node.GetArgs()[i]; AALocalDecl formal = (AALocalDecl) method.GetFormals()[i]; if (oldParameterTypes.ContainsKey(formal)) type = oldParameterTypes[formal];// data.ExpTypes[arg]; else type = formal.GetType(); if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null) { if (formal.GetRef() != null && arg is ALvalueExp) { ALvalueExp aArg = (ALvalueExp) arg; if (aArg.GetLvalue() is APointerLvalue) { APointerLvalue pointer = (APointerLvalue) aArg.GetLvalue(); if (Util.TypesEqual(formal.GetType(), data.ExpTypes[pointer.GetBase()], data)) {//Just send the arg aArg.ReplaceBy(pointer.GetBase()); continue; } } } TurnDynamic(arg, formal, oldParameterTypes.ContainsKey(formal) ? oldParameterTypes[formal] : formal.GetType(), formal.GetOut() == null, formal.GetRef() != null || formal.GetOut() != null); } } //Do return stm type = data.ExpTypes[node]; if (Util.IsBulkCopy(type)) { PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock)pStm.Parent(); bool isReturnUsed = !(node.Parent() is AExpStm); if (isReturnUsed) { //Make //var bulkCopyVar = <node>(...); //<usage>... *bulkCopyVar ... </usage> //delete bulkCopyVar; bool isArray = type is AArrayTempType; AALocalDecl newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), isArray ? new ADynamicArrayType( new TLBracket("["), Util.MakeClone( ((AArrayTempType) type). GetType(), data)) : Util.MakeClone(type, data)), new TIdentifier("bulkCopyVar"), null); data.ExpTypes[node] = newLocal.GetType(); ALocalLvalue newLocalRef; ALvalueExp newLocalRefExp; newLocalRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); newLocalRefExp = new ALvalueExp(newLocalRef); APointerLvalue newLocalPointer = new APointerLvalue(new TStar("*"), newLocalRefExp); ALvalueExp newLocalPointerExp = new ALvalueExp(newLocalPointer); node.ReplaceBy(newLocalPointerExp); data.LocalLinks[newLocalRef] = newLocal; data.LvalueTypes[newLocalRef] = data.ExpTypes[newLocalRefExp] = newLocal.GetType(); data.LvalueTypes[newLocalPointer] = data.ExpTypes[newLocalPointerExp] = ((APointerType) newLocal.GetType()).GetType(); newLocal.SetInit(node); newLocalRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); newLocalRefExp = new ALvalueExp(newLocalRef); data.LocalLinks[newLocalRef] = newLocal; data.LvalueTypes[newLocalRef] = data.ExpTypes[newLocalRefExp] = newLocal.GetType(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), newLocal)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, new ADeleteStm(new TDelete("delete"), newLocalRefExp)); } else { //Make delete <node>(...); pStm.ReplaceBy(new ADeleteStm(new TDelete("delete"), node)); } } base.OutASimpleInvokeExp(node); }
public override void CaseAMethodDecl(AMethodDecl node) { if (processedMethods.Contains(node)) return; processedMethods.Add(node); //For each bulk copy param, make it a pointer type foreach (AALocalDecl formal in node.GetFormals()) { PType type = formal.GetType(); if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null) { if (type is AArrayTempType) {//make dynamic array AArrayTempType aType = (AArrayTempType) type; List<PExp> exps = new List<PExp>(); PType newType = new APointerType(new TStar("*"), new ADynamicArrayType((TLBracket)aType.GetToken().Clone(), Util.MakeClone(aType.GetType(), data))); /*exps.AddRange(data.ExpTypes.Where(k => k.Value == type).Select(k => k.Key)); foreach (PExp exp in exps) { data.ExpTypes[exp] = newType; }*/ formal.SetType(newType); foreach (KeyValuePair<ALocalLvalue, AALocalDecl> pair in data.LocalLinks) { if (pair.Value == formal) {//Replace with *lvalue ALvalueExp innerExp = new ALvalueExp(); APointerLvalue replacement = new APointerLvalue(new TStar("*"), innerExp); pair.Key.ReplaceBy(replacement); innerExp.SetLvalue(pair.Key); data.ExpTypes[innerExp] = data.LvalueTypes[pair.Key] = formal.GetType(); data.LvalueTypes[replacement] = ((APointerType)newType).GetType(); //if (replacement.Parent() is ALvalueExp) // data.ExpTypes[(PExp)replacement.Parent()] = data.LvalueTypes[replacement]; } } } else {//Make pointer formal.SetType(new APointerType(new TStar("*"), type)); foreach (KeyValuePair<ALocalLvalue, AALocalDecl> pair in data.LocalLinks) { if (pair.Value == formal) {//Replace with *lvalue ALvalueExp innerExp = new ALvalueExp(); APointerLvalue replacement = new APointerLvalue(new TStar("*"), innerExp); pair.Key.ReplaceBy(replacement); innerExp.SetLvalue(pair.Key); data.ExpTypes[innerExp] = data.LvalueTypes[pair.Key] = formal.GetType(); data.LvalueTypes[replacement] = type; } } } } } if (Util.IsBulkCopy(node.GetReturnType())) { PType oldType = node.GetReturnType(); PType newType; if (node.GetReturnType() is AArrayTempType) {//make dynamic array AArrayTempType aType = (AArrayTempType) node.GetReturnType(); newType = new APointerType(new TStar("*"), new ADynamicArrayType((TLBracket) aType.GetToken().Clone(), Util.MakeClone(aType.GetType(), data))); node.SetReturnType(newType); } else {//Make pointer newType = new APointerType(new TStar("*"), node.GetReturnType()); node.SetReturnType(newType); } /*List<PExp> exps = new List<PExp>(); exps.AddRange(data.ExpTypes.Where(k => k.Value == oldType).Select(k => k.Key)); foreach (PExp exp in exps) { data.ExpTypes[exp] = newType; } List<PLvalue> lvalues = new List<PLvalue>(); lvalues.AddRange(data.LvalueTypes.Where(k => k.Value == oldType).Select(k => k.Key)); foreach (PLvalue lvalue in lvalues) { data.LvalueTypes[lvalue] = newType; }*/ } base.CaseAMethodDecl(node); }
public virtual void InAPointerLvalue(APointerLvalue node) { DefaultIn(node); }
public static PLvalue Link(AAName name, Node refNode, List<Node> list, SharedData data) { List<TIdentifier> identifierList = new List<TIdentifier>(); { int count = name.GetIdentifier().Count; if (count < list.Count) { for (int i = 0; i < list.Count - count; i++) { if (list[i] is AStructDecl) identifierList.Add(((AStructDecl)list[i]).GetName()); } for (int i = 0; i < count; i++) { TIdentifier iden = (TIdentifier)name.GetIdentifier()[i]; identifierList.Add(iden); } } else for (int i = count - list.Count; i < count; i++) { TIdentifier iden = (TIdentifier)name.GetIdentifier()[i]; identifierList.Add(iden); } } PLvalue baseLvalue = null; Node node = list[0]; list.RemoveAt(0); TIdentifier identifier = identifierList[0]; identifierList.RemoveAt(0); if (node is AALocalDecl) { AALocalDecl aNode = (AALocalDecl)node; if (node.Parent() is AStructDecl) {//Struct local //Make it this->var or this.var AStructDecl pStruct = Util.GetAncestor<AStructDecl>(node); if (pStruct.GetClassToken() != null || Util.HasAncestor<AConstructorDecl>(refNode) || Util.HasAncestor<ADeconstructorDecl>(refNode)) {//(*this). baseLvalue = new AThisLvalue(new TThis("this")); baseLvalue = new APointerLvalue(new TStar("*"), new ALvalueExp(baseLvalue)); baseLvalue = new AStructLvalue(new ALvalueExp(baseLvalue), new ADotDotType(new TDot(".")), identifier); data.StructFieldLinks[(AStructLvalue)baseLvalue] = aNode; } else {//struct. baseLvalue = new AStructFieldLvalue(identifier); data.StructMethodFieldLinks[(AStructFieldLvalue)baseLvalue] = aNode; } } else {//Method/constructor/deconstructor local ALocalLvalue replaceNode = new ALocalLvalue(identifier); data.LocalLinks[replaceNode] = aNode; baseLvalue = replaceNode; } } else if (node is APropertyDecl) { APropertyDecl aNode = (APropertyDecl)node; if (Util.HasAncestor<AStructDecl>(node)) {//Property in current struct AStructDecl pStruct = Util.GetAncestor<AStructDecl>(node); if (pStruct.GetClassToken() != null || Util.HasAncestor<AConstructorDecl>(refNode) || Util.HasAncestor<ADeconstructorDecl>(refNode)) {//(*this). baseLvalue = new AThisLvalue(new TThis("this")); baseLvalue = new APointerLvalue(new TStar("*"), new ALvalueExp(baseLvalue)); baseLvalue = new AStructLvalue(new ALvalueExp(baseLvalue), new ADotDotType(new TDot(".")), identifier); data.StructPropertyLinks[(AStructLvalue)baseLvalue] = aNode; } else {//struct. baseLvalue = new AStructFieldLvalue(identifier); data.StructMethodPropertyLinks[(AStructFieldLvalue)baseLvalue] = aNode; } } else {//Global property baseLvalue = new APropertyLvalue(identifier); data.PropertyLinks[(APropertyLvalue)baseLvalue] = aNode; } } else if (node is AFieldDecl) { baseLvalue = new AFieldLvalue(identifier); data.FieldLinks[(AFieldLvalue)baseLvalue] = (AFieldDecl)node; } else if (node is AStructDecl) { AStructDecl targetStruct = (AStructDecl)node; node = list[0]; list.RemoveAt(0); identifier = identifierList[0]; identifierList.RemoveAt(0); AStructFieldLvalue lvalue = new AStructFieldLvalue(identifier); if (node is AALocalDecl) data.StructMethodFieldLinks[lvalue] = (AALocalDecl)node; else data.StructMethodPropertyLinks[lvalue] = (APropertyDecl)node; baseLvalue = lvalue; } while (list.Count > 0) { node = list[0]; list.RemoveAt(0); identifier = identifierList[0]; identifierList.RemoveAt(0); baseLvalue = new AStructLvalue(new ALvalueExp(baseLvalue), new ADotDotType(new TDot(".")), identifier); if (node is AALocalDecl) {//Struct local data.StructFieldLinks[(AStructLvalue) baseLvalue] = (AALocalDecl) node; } else if (node is APropertyDecl) {//Struct property data.StructPropertyLinks[(AStructLvalue) baseLvalue] = (APropertyDecl) node; } //Don't link array length stuff } return baseLvalue; }
public virtual void OutAPointerLvalue(APointerLvalue node) { DefaultOut(node); }
public override void OutAPointerLvalue(APointerLvalue node) { data.LvalueTypes[node] = ((APointerType) data.ExpTypes[node.GetBase()]).GetType(); }