mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 07:49:08 +02:00
* 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 -
This commit is contained in:
parent
8af064cf00
commit
5ed31d4345
@ -309,12 +309,11 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
return $name;
|
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
|
// first_bitpacked_type so that the compiler may correctly align it
|
||||||
// (it does not do that currently, but this at least provides a
|
// the actual bitpacked record is embedded inside
|
||||||
// hint to the programmer)
|
|
||||||
function BitPackedForceAlignment($first_bitpacked_type, $firstindent, $otherindents) {
|
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;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,7 +596,7 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
function MakeFieldBitPacked ($ioType, $field, &$bitpacked) {
|
function MakeFieldBitPacked ($ioType, $field, &$bitpacked) {
|
||||||
$bitpacked = false;
|
$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];
|
$length = (int)$bitpack[1];
|
||||||
if ($length > 1) {
|
if ($length > 1) {
|
||||||
$ioType = "0..((1 shl $length)-1)";
|
$ioType = "0..((1 shl $length)-1)";
|
||||||
@ -2426,7 +2425,7 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parses $line into the combined $struct_fields string
|
// 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)) {
|
if (preg_match($this->pregex_function_pointer, $line, $captures)) {
|
||||||
$struct_fields .= " " . $this->ParseFunctionDeclaration($captures[1], $captures[2], $captures[3], $captures[4], false, "");
|
$struct_fields .= " " . $this->ParseFunctionDeclaration($captures[1], $captures[2], $captures[3], $captures[4], false, "");
|
||||||
$all_bitpacked = 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");
|
// print("field: '$new_field', bitpacked: $field_bitpacked, any: $found_any_bitpacked, all: $all_bitpacked\n");
|
||||||
if ($new_field != "") {
|
if ($new_field != "") {
|
||||||
$found_any_bitpacked |= $field_bitpacked;
|
$found_any_bitpacked |= $field_bitpacked;
|
||||||
if ($struct_fields == "") {
|
if (!$any_field_parsed) {
|
||||||
$all_bitpacked = $field_bitpacked;
|
$all_bitpacked = $field_bitpacked;
|
||||||
$first_bitpacked_type = $bitpacked_real_type;
|
$first_bitpacked_type = $bitpacked_real_type;
|
||||||
|
$any_field_parsed=true;
|
||||||
}
|
}
|
||||||
else $all_bitpacked &= $field_bitpacked;
|
else $all_bitpacked &= $field_bitpacked;
|
||||||
$struct_fields .= " " . $new_field . $this->AppendEOLComment() . "\n";
|
$struct_fields .= " " . $new_field . $this->AppendEOLComment() . "\n";
|
||||||
@ -2506,6 +2506,7 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
function ParseHeaderTypes ($file) {
|
function ParseHeaderTypes ($file) {
|
||||||
$contents = file_get_contents($file);
|
$contents = file_get_contents($file);
|
||||||
$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
|
$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
|
||||||
|
$any_field_parsed = false;
|
||||||
$any_field_bitpacked = false;
|
$any_field_bitpacked = false;
|
||||||
$all_fields_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";
|
if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) $struct_fields .= "$macro\n";
|
||||||
|
|
||||||
// collect fields
|
// 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
|
// got end of struct
|
||||||
if (ereg("^}[[:space:]]*([a-zA-Z_0-9]+);", $line, $captures)) {
|
if (ereg("^}[[:space:]]*([a-zA-Z_0-9]+);", $line, $captures)) {
|
||||||
@ -2557,13 +2558,11 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
// ignore this struct
|
// ignore this struct
|
||||||
if (in_array($struct_name, $this->ignore_types)) continue;
|
if (in_array($struct_name, $this->ignore_types)) continue;
|
||||||
|
|
||||||
if ($all_fields_bitpacked) {
|
$struct = "$struct_comment$struct_name = $this->record_keyword\n";
|
||||||
$struct = "$struct_comment$struct_name = $this->bitpacked_record_keyword\n";
|
if ($any_field_bitpacked) {
|
||||||
$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, " ", " ") . "\n";
|
$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, " ", " ") . "\n";
|
||||||
$struct_fields = str_replace(" "," ",$struct_fields);
|
$struct_fields = str_replace(" "," ",$struct_fields);
|
||||||
$struct_fields .= " );\n";
|
$struct_fields .= " end;\n );\n";
|
||||||
} else {
|
|
||||||
$struct = "$struct_comment$struct_name = $this->record_keyword\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$struct .= $struct_fields;
|
$struct .= $struct_fields;
|
||||||
@ -2577,6 +2576,7 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
$this->dump[$file_name]["types"]["structs"][] = $struct;
|
$this->dump[$file_name]["types"]["structs"][] = $struct;
|
||||||
$this->dump["global_structs"][] = $struct_name;
|
$this->dump["global_structs"][] = $struct_name;
|
||||||
$got_struct = false;
|
$got_struct = false;
|
||||||
|
$any_field_parsed = false;
|
||||||
$any_field_bitpacked = false;
|
$any_field_bitpacked = false;
|
||||||
$all_fields_bitpacked = false;
|
$all_fields_bitpacked = false;
|
||||||
}
|
}
|
||||||
@ -2597,17 +2597,17 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
// parse each line
|
// parse each line
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$field = trim($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
|
// merge the fields into the definition
|
||||||
$struct = "$comment\n"."$struct_name = ";
|
$struct = "$comment\n"."$struct_name = ";
|
||||||
if ($all_fields_bitpacked) {
|
$struct .= "$this->record_keyword\n";
|
||||||
$struct .= "$this->bitpacked_record_keyword\n";
|
if ($any_field_bitpacked) {
|
||||||
$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, " ", " ") . "\n";
|
$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, " ", " ") . "\n";
|
||||||
$single_struct_fields = str_replace(" "," ",$single_struct_fields);
|
$single_struct_fields = str_replace(" "," ",$single_struct_fields);
|
||||||
$single_struct_fields .= " );\n";
|
$single_struct_fields .= " end;\n );\n";
|
||||||
} else $struct .= "$this->record_keyword\n";
|
} else ;
|
||||||
$struct .= $single_struct_fields;
|
$struct .= $single_struct_fields;
|
||||||
$struct .= " end$deprecatedmods;\n";
|
$struct .= " end$deprecatedmods;\n";
|
||||||
// pointer type
|
// pointer type
|
||||||
@ -2615,6 +2615,7 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
|
|
||||||
$this->dump[$file_name]["types"]["structs"][] = $struct;
|
$this->dump[$file_name]["types"]["structs"][] = $struct;
|
||||||
$this->dump["global_structs"][] = $struct_name;
|
$this->dump["global_structs"][] = $struct_name;
|
||||||
|
$any_field_parsed = false;
|
||||||
$any_field_bitpacked = false;
|
$any_field_bitpacked = false;
|
||||||
$all_fields_bitpacked = false;
|
$all_fields_bitpacked = false;
|
||||||
//print("$single_struct_fields\n");
|
//print("$single_struct_fields\n");
|
||||||
@ -2629,6 +2630,7 @@ class ObjectivePParser extends ObjectivePParserBase {
|
|||||||
$this->ResetComment();
|
$this->ResetComment();
|
||||||
if ($struct_comment != "") $struct_comment = "$struct_comment\n";
|
if ($struct_comment != "") $struct_comment = "$struct_comment\n";
|
||||||
$got_struct = true;
|
$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;
|
$this->dump[$file_name]["classes"][$current]["ivars_structs"][] = $struct;
|
||||||
|
|
||||||
// print inline-record type
|
// print inline-record type
|
||||||
|
$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->record_keyword;
|
||||||
if ($struct["bitpacked"]) {
|
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"], " ", " ");
|
$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
|
// print fields
|
||||||
if ($struct["fields"]) {
|
if ($struct["fields"]) {
|
||||||
foreach ($struct["fields"] as $field) $this->dump[$file_name]["classes"][$current]["ivars"][] = " ".$field;
|
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;";
|
$this->dump[$file_name]["classes"][$current]["ivars"][] = " end;";
|
||||||
|
|
||||||
$struct = null;
|
$struct = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user