public override void VisitConstant(Constant c) { if (!c.IsValid || c is BigConstant) { return; } DataType dt = c.TypeVariable !.DataType; int? offset = StructureField.ToOffset(c); if (offset == null) { return; } switch (dt) { case Pointer ptr: // C is a constant pointer. if (offset.Value == 0) { return; // null pointer is null (//$REVIEW: except for some platforms + archs) } var pointee = ptr.Pointee; var segPointee = pointee.ResolveAs <StructureType>(); if (segPointee != null && segPointee.IsSegment) { //$TODO: these are getting merged earlier, perhaps this is the right place to do those merges? return; } var strGlobals = Globals.TypeVariable !.Class.ResolveAs <StructureType>(); if (strGlobals !.Fields.AtOffset(offset.Value) == null) { if (!IsInsideArray(strGlobals, offset.Value, pointee) && !IsInsideStruct(strGlobals, offset.Value)) { strGlobals.Fields.Add(offset.Value, pointee); } } return; case MemberPointer mptr: // C is a constant offset into a segment. var seg = ((Pointer)mptr.BasePointer).Pointee.ResolveAs <StructureType>(); if (seg != null && //$DEBUG seg.Fields.AtOffset(offset.Value) == null) { seg.Fields.Add(offset.Value, mptr.Pointee); } // VisitConstantMemberPointer(offset, mptr); return; } }
DataType PromoteToCString(Constant c, DataType charType) { // Note that it's OK if there is no global field corresponding to a string constant. // It means that the string will be emitted "inline" in the code and not // as a separate global character array. var dt = StringType.NullTerminated(charType); var field = GlobalVars !.Fields.AtOffset(c.ToInt32()); if (field != null) { field.DataType = dt; } return(dt); }