2
0
Эх сурвалжийг харах

added alignment for record types

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6396 8c9fc860-2736-0410-a75d-ab315db34111
felixf 9 жил өмнө
parent
commit
079df6faad

+ 6 - 6
source/FoxGlobal.Mod

@@ -299,7 +299,7 @@ TYPE
 			IF baseType # NIL THEN
 				offset := baseType.sizeInBits; alignment := baseType.alignmentInBits;
 			ELSE
-				offset := 0; alignment := dataUnit;
+				offset := 0; alignment := x.alignmentInBits;
 			END;
 
 			variable := x.recordScope.firstVariable;
@@ -319,7 +319,7 @@ TYPE
 				INC(offset,size);
 				variable := variable.nextVariable;
 			END;
-			x.SetAlignment(alignment);
+			x.SetAlignmentInBits(alignment);
 			Basic.Align(offset, alignment); (* strictly speaking not necessary, but with the old object file format otherwise problems with the GC show up *)
 			x.SetSize(offset);
 			RETURN TRUE
@@ -355,7 +355,7 @@ TYPE
 				INC(offset,size);
 				variable := variable.nextVariable;
 			END;
-			x.SetAlignment(alignment);
+			x.SetAlignmentInBits(alignment);
 			Basic.Align(offset, alignment); (* strictly speaking not necessary, but with the old object file format otherwise problems with the GC show up *)
 			x.SetSize(offset);
 			RETURN TRUE
@@ -581,7 +581,7 @@ TYPE
 		BEGIN
 			type := type.resolved;
 			IF type IS SyntaxTree.RecordType THEN
-				IF type.alignmentInBits < 0 THEN
+				IF type.alignmentInBits <= 0 THEN
 					IF GenerateRecordOffsets(type(SyntaxTree.RecordType)) THEN
 						result := type.alignmentInBits
 					END
@@ -589,13 +589,13 @@ TYPE
 					result := type.alignmentInBits
 				END;
 			ELSIF type IS SyntaxTree.ArrayType THEN
-				IF type.alignmentInBits <0 THEN
+				IF type.alignmentInBits <= 0 THEN
 					IF type(SyntaxTree.ArrayType).form = SyntaxTree.Static THEN
 						result := AlignmentOf(alignment,type(SyntaxTree.ArrayType).arrayBase.resolved);
 					ELSE
 						result := alignment.max
 					END;
-					type.SetAlignment(result)
+					type.SetAlignmentInBits(result)
 				ELSE
 					result := type.alignmentInBits
 				END;

+ 33 - 2
source/FoxIntermediateBackend.Mod

@@ -343,7 +343,7 @@ TYPE
 		END VisitOperator;
 
 		PROCEDURE VisitVariable(x: SyntaxTree.Variable);
-		VAR name: Basic.SegmentedName; irv: IntermediateCode.Section;
+		VAR name: Basic.SegmentedName; irv: IntermediateCode.Section; align: LONGINT;
 		BEGIN
 			IF x.externalName # NIL THEN RETURN END;
 			IF (currentScope IS SyntaxTree.ModuleScope) OR (currentScope IS SyntaxTree.CellScope) & ~backend.cellsAreObjects THEN
@@ -353,7 +353,12 @@ TYPE
 				irv.SetExported(IsExported(x));
 				irv.SetOffset(ToMemoryUnits(system,x.offsetInBits));
 				irv.Emit(Reserve(x.position,ToMemoryUnits(system,system.SizeOf(x.type))));
-				irv.SetPositionOrAlignment(x.fixed, x.alignment);
+				IF ~x.fixed THEN
+					align := CommonAlignment(x.alignment, ToMemoryUnits(system, system.AlignmentOf(system.variableAlignment, x.type)));
+				ELSE
+					align := x.alignment;
+				END;
+				irv.SetPositionOrAlignment(x.fixed, align);
 				meta.CheckTypeDeclaration(x.type);
 			ELSIF currentScope IS SyntaxTree.RecordScope THEN
 			ELSIF currentScope IS SyntaxTree.ProcedureScope THEN
@@ -12534,6 +12539,32 @@ TYPE
 		statCoopTraceModule)
 	END Statistics;
 
+
+	PROCEDURE GCD(a,b: LONGINT): LONGINT;
+	VAR h: LONGINT;
+	BEGIN
+		WHILE b # 0 DO
+			h := a MOD b;
+			a := b;
+			b := h;
+		END;
+		RETURN a
+	END GCD;
+
+	PROCEDURE SCM(a,b: LONGINT): LONGINT;
+	BEGIN
+		RETURN a*b DIV GCD(a,b)
+	END SCM;
+
+	PROCEDURE CommonAlignment(a,b: LONGINT): LONGINT;
+	BEGIN
+		(*TRACE(a,b);*)
+		IF a = 0 THEN RETURN b
+		ELSIF b = 0 THEN RETURN a
+		ELSE RETURN SCM(a,b)
+		END;
+	END CommonAlignment;
+	
 	PROCEDURE PassBySingleReference(parameter: SyntaxTree.Parameter): BOOLEAN;
 	BEGIN
 		IF parameter.kind = SyntaxTree.ValueParameter THEN RETURN FALSE

+ 5 - 0
source/FoxParser.Mod

@@ -1349,6 +1349,7 @@ TYPE
 			recordType: SyntaxTree.RecordType;
 			recordScope: SyntaxTree.RecordScope;
 			qualifiedIdentifier: SyntaxTree.QualifiedIdentifier;  flags: SET;  qualifiedType: SyntaxTree.QualifiedType;
+			modifier: SyntaxTree.Modifier;
 		BEGIN
 			IF Trace THEN S( "RecordType" ) END;
 			(* record symbol already consumed *)
@@ -1356,6 +1357,10 @@ TYPE
 			flags := {};
 			recordScope := SyntaxTree.NewRecordScope(parentScope);
 			recordType := SyntaxTree.NewRecordType( position, parentScope, recordScope);
+			IF Optional( Scanner.LeftBrace ) THEN
+				modifier := Flags();
+				recordType.SetModifiers(modifier);
+			END;
 			IF Optional( Scanner.LeftParenthesis ) THEN
 				qualifiedIdentifier := QualifiedIdentifier();
 				qualifiedType := SyntaxTree.NewQualifiedType(qualifiedIdentifier.position, parentScope, qualifiedIdentifier );

+ 8 - 0
source/FoxSemanticChecker.Mod

@@ -881,6 +881,8 @@ TYPE
 			numberMethods: LONGINT; recordBase, recordType: SyntaxTree.RecordType; procedure: SyntaxTree.Procedure;
 			symbol: SyntaxTree.Symbol; isRealtime: BOOLEAN;
 			hasPointers: BOOLEAN;
+			modifiers: SyntaxTree.Modifier;
+			value: LONGINT;
 
 			PROCEDURE IsPointerToRecord(type: SyntaxTree.Type; VAR recordType: SyntaxTree.RecordType): BOOLEAN;
 			BEGIN
@@ -899,7 +901,13 @@ TYPE
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 				hasPointers := FALSE;
+				
+				modifiers := x.modifiers;
+				IF HasValue(modifiers,Global.NameAligned,position,value) THEN x.SetAlignmentInBits(value*system.dataUnit) END;
+				CheckModifiers(modifiers, TRUE);
+				
 				IF x.baseType # NIL THEN
+
 					position := x.baseType.position;
 					baseType := ResolveType(x.baseType);
 					resolved := baseType.resolved;

+ 9 - 3
source/FoxSyntaxTree.Mod

@@ -429,7 +429,7 @@ TYPE
 			scope := NIL;
 			resolved := SELF;
 			sizeInBits := MIN(LONGINT);
-			alignmentInBits := MIN(LONGINT);
+			alignmentInBits := 0;
 			isRealtime := FALSE;
 			recursion := FALSE;
 			hasPointers := FALSE;
@@ -440,9 +440,9 @@ TYPE
 		BEGIN SELF.sizeInBits := sizeInBits
 		END SetSize;
 
-		PROCEDURE SetAlignment*(alignmentInBits: LONGINT);
+		PROCEDURE SetAlignmentInBits*(alignmentInBits: LONGINT);
 		BEGIN SELF.alignmentInBits := alignmentInBits
-		END SetAlignment;
+		END SetAlignmentInBits;
 
 		PROCEDURE End*( position: LONGINT );
 		BEGIN SELF.endposition := position;
@@ -1419,6 +1419,7 @@ TYPE
 			recordScope-:RecordScope;
 			baseType-: Type;
 			pointerType-: PointerType; (* for support of A = POINTER TO RECORD ... END and B = POINTER TO RECORD (A) END; *)
+			modifiers-: Modifier;
 			isObject-,isProtected: BOOLEAN;
 
 			(* a math array type describing an object's array structure; NIL if the type does not exhibit an array structure *)
@@ -1438,8 +1439,13 @@ TYPE
 			recordScope.ownerRecord := SELF;
 			isObject := FALSE; isProtected := FALSE;
 			arrayStructure := NIL;
+			modifiers := NIL;
 		END InitRecordType;
 
+		PROCEDURE SetModifiers*(flag: Modifier);
+		BEGIN SELF.modifiers := flag;
+		END SetModifiers;
+		
 		PROCEDURE SetBaseType*( type: Type );
 		BEGIN
 			baseType := type; IF (baseType # NIL) & (baseType.hasPointers) THEN hasPointers := TRUE END;