mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 22:26:00 +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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
Loading…
Reference in New Issue
Block a user