瀏覽代碼

* mark records containing at least one bitpacked field as "bitpacked" rather
than only record containing nothing but bitpacked fields (although in
theory this can also cause errors, it results in correct data layouts
for all Cocoa structs while the previous code didn't)
* changed the translation of bitpacked structs so that the compiler will
properly align them. This requires that all bitpacked fields are
wrapped into a separate record though, so all fields are now accessible
via recname.data.field instead of via recname.field. Since all fields
in the Cocoa classes are private, this should not cause problems
(except if exported record types are also used elsewhere)

git-svn-id: trunk@18113 -

Jonas Maebe 14 年之前
父節點
當前提交
5ed31d4345
共有 1 個文件被更改,包括 25 次插入23 次删除
  1. 25 23
      packages/cocoaint/utils/source/objp.php

+ 25 - 23
packages/cocoaint/utils/source/objp.php

@@ -309,12 +309,11 @@ class ObjectivePParser extends ObjectivePParserBase {
 		return $name;
 	}
 	
-	// create a variant record with a first anonymous field of type
+	// create a variant normal record with a first anonymous field of type
 	// first_bitpacked_type so that the compiler may correctly align it
-	// (it does not do that currently, but this at least provides a
-	//  hint to the programmer)
+	// the actual bitpacked record is embedded inside
 	function BitPackedForceAlignment($first_bitpacked_type, $firstindent, $otherindents) {
-		$result = $firstindent . "case byte of\n" . $otherindents ."0: (" . $this->GetAnonBitFieldName() . ": $first_bitpacked_type);\n" . $otherindents . "1: (";
+		$result = $firstindent . "case byte of\n" . $otherindents ."0: (" . $this->GetAnonBitFieldName() . ": $first_bitpacked_type);\n" . $otherindents . "1: (data: bitpacked record";
 		return $result;
 	}
 	
@@ -597,7 +596,7 @@ class ObjectivePParser extends ObjectivePParserBase {
 	function MakeFieldBitPacked ($ioType, $field, &$bitpacked) {
 		$bitpacked = false;
 		
-		if (preg_match("!:([0-9]+)\s*(?:__attribute__\(\([^)]*\)\))?\s*;$!", $field, $bitpack)) {
+		if (preg_match("!:([0-9]+)\s*(?:__attribute__\(\([^)]*\)\))?\s*;\s*$!", $field, $bitpack)) {
 			$length = (int)$bitpack[1];
 			if ($length > 1) {
 				$ioType = "0..((1 shl $length)-1)";
@@ -2426,7 +2425,7 @@ class ObjectivePParser extends ObjectivePParserBase {
 	}
 	
 	// Parses $line into the combined $struct_fields string
-	function ParseStructFields ($line, $protected_keywords, &$struct_fields, &$found_any_bitpacked, &$all_bitpacked, &$first_bitpacked_type) {
+	function ParseStructFields ($line, $protected_keywords, &$struct_fields, &$any_field_parsed, &$found_any_bitpacked, &$all_bitpacked, &$first_bitpacked_type) {
 		if (preg_match($this->pregex_function_pointer, $line, $captures)) {
 			$struct_fields .= "    " . $this->ParseFunctionDeclaration($captures[1], $captures[2], $captures[3], $captures[4], false, "");
 			$all_bitpacked = false;
@@ -2438,9 +2437,10 @@ class ObjectivePParser extends ObjectivePParserBase {
 //			print("field: '$new_field', bitpacked: $field_bitpacked, any: $found_any_bitpacked, all: $all_bitpacked\n");
 			if ($new_field != "") {
 				$found_any_bitpacked |= $field_bitpacked;
-				if ($struct_fields == "") {
+				if (!$any_field_parsed) {
 					$all_bitpacked = $field_bitpacked;
 					$first_bitpacked_type = $bitpacked_real_type;
+					$any_field_parsed=true;
 				}
 				else $all_bitpacked &= $field_bitpacked;
 				$struct_fields .= "    " . $new_field . $this->AppendEOLComment() . "\n";
@@ -2506,6 +2506,7 @@ class ObjectivePParser extends ObjectivePParserBase {
 	function ParseHeaderTypes ($file) {
 			$contents = file_get_contents($file);
 			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));	
+			$any_field_parsed = false;
 			$any_field_bitpacked = false;
 			$all_fields_bitpacked = false;
 			
@@ -2543,7 +2544,7 @@ class ObjectivePParser extends ObjectivePParserBase {
 					if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) $struct_fields .= "$macro\n";
 					
 					// collect fields
-					$this->ParseStructFields($line, array(), $struct_fields, $any_field_bitpacked, $all_fields_bitpacked, $first_bitpacked_type);
+					$this->ParseStructFields($line, array(), $struct_fields, $any_field_parsed, $any_field_bitpacked, $all_fields_bitpacked, $first_bitpacked_type);
 					
 					// got end of struct
 					if (ereg("^}[[:space:]]*([a-zA-Z_0-9]+);", $line, $captures)) {
@@ -2557,13 +2558,11 @@ class ObjectivePParser extends ObjectivePParserBase {
 						// ignore this struct
 						if (in_array($struct_name, $this->ignore_types)) continue;
 						
-						if ($all_fields_bitpacked) {
-							$struct = "$struct_comment$struct_name = $this->bitpacked_record_keyword\n";
+						$struct = "$struct_comment$struct_name = $this->record_keyword\n";
+						if ($any_field_bitpacked) {
 							$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, "    ", "    ") . "\n";
 							$struct_fields = str_replace("    ","          ",$struct_fields);
-							$struct_fields .= "       );\n";
-						} else {
-							$struct = "$struct_comment$struct_name = $this->record_keyword\n";
+							$struct_fields .= "         end;\n       );\n";
 						}
 						
 						$struct .= $struct_fields;
@@ -2577,6 +2576,7 @@ class ObjectivePParser extends ObjectivePParserBase {
 						$this->dump[$file_name]["types"]["structs"][] = $struct;
 						$this->dump["global_structs"][] = $struct_name;
 						$got_struct = false;
+						$any_field_parsed = false;
 						$any_field_bitpacked = false;
 						$all_fields_bitpacked = false;
 					}
@@ -2597,17 +2597,17 @@ class ObjectivePParser extends ObjectivePParserBase {
 						// parse each line
 						foreach ($fields as $field) {
 							$field = trim($field);
-							$this->ParseStructFields($field.";", array(), $single_struct_fields, $any_field_bitpacked, $all_fields_bitpacked, $first_bitpacked_type);
+							$this->ParseStructFields($field.";", array(), $single_struct_fields, $any_field_parsed, $any_field_bitpacked, $all_fields_bitpacked, $first_bitpacked_type);
 						}
 						
 						// merge the fields into the definition
 						$struct = "$comment\n"."$struct_name = ";
-						if ($all_fields_bitpacked) {
-							$struct .= "$this->bitpacked_record_keyword\n";
+						$struct .= "$this->record_keyword\n";
+						if ($any_field_bitpacked) {
 							$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, "    ", "    ") . "\n";
 							$single_struct_fields = str_replace("    ","          ",$single_struct_fields);
-							$single_struct_fields .= "       );\n";
-						}	else $struct .= "$this->record_keyword\n";
+							$single_struct_fields .= "         end;\n       );\n";
+						}	else ;
 						$struct .= $single_struct_fields;
 						$struct .= "  end$deprecatedmods;\n";
 						// pointer type
@@ -2615,6 +2615,7 @@ class ObjectivePParser extends ObjectivePParserBase {
 						
 						$this->dump[$file_name]["types"]["structs"][] = $struct;
 						$this->dump["global_structs"][] = $struct_name;
+						$any_field_parsed = false;
 						$any_field_bitpacked = false;
 						$all_fields_bitpacked = false;
 						//print("$single_struct_fields\n");
@@ -2629,6 +2630,7 @@ class ObjectivePParser extends ObjectivePParserBase {
 						$this->ResetComment();
 						if ($struct_comment != "") $struct_comment = "$struct_comment\n";
 						$got_struct = true;
+						print("Parsing struct $struct_name\n");
 					}
 				}
 
@@ -3314,19 +3316,19 @@ class ObjectivePParser extends ObjectivePParserBase {
 						$this->dump[$file_name]["classes"][$current]["ivars_structs"][] = $struct;
 						
 						// print inline-record type
+						$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->record_keyword;
 						if ($struct["bitpacked"]) {
-							$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->bitpacked_record_keyword;
 							$this->dump[$file_name]["classes"][$current]["ivars"][] = $this->BitPackedForceAlignment($struct["bitpacked_first_type"], "  ", "       ");
-						} else {
-							$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->record_keyword;
 						}
 						
-						
 						// print fields
 						if ($struct["fields"]) {
 							foreach ($struct["fields"] as $field) $this->dump[$file_name]["classes"][$current]["ivars"][] = "    ".$field;
 						}
-						if ($struct["bitpacked"]) $this->dump[$file_name]["classes"][$current]["ivars"][] = "  );";
+						if ($struct["bitpacked"]) {
+							$this->dump[$file_name]["classes"][$current]["ivars"][] = "   end;";
+							$this->dump[$file_name]["classes"][$current]["ivars"][] = "  );";
+						}
 						$this->dump[$file_name]["classes"][$current]["ivars"][] = "  end;";
 						
 						$struct = null;