Unverified Commit 7f37f6af by Melvin Klimke Committed by GitHub

Adapt datatype conversion (#201)

parent 4746e4d3
......@@ -152,13 +152,14 @@ pub enum Datatype {
impl From<String> for Datatype {
/// The purpose of this conversion is to locate parameters to variadic functions.
/// Therefore, char types are mapped to integer types since they undergo the default
/// Therefore, char types have to be mapped to the integer size since they undergo the default
/// argument promotion. (e.g. 1 byte char -> 4 byte integer)
/// The same holds for all float types that are promoted to doubles. (e.g. 8 byte float -> 16 byte double)
fn from(specifier: String) -> Self {
match specifier.as_str() {
"c" | "C" | "d" | "i" | "u" | "o" | "x" | "X" | "hi" | "hd" | "hu" => Datatype::Integer,
"s" | "S" | "n" | "p" => Datatype::Pointer,
"c" | "C" => Datatype::Char,
"d" | "i" | "u" | "o" | "p" | "x" | "X" | "hi" | "hd" | "hu" => Datatype::Integer,
"s" | "S" | "n" => Datatype::Pointer,
"lf" | "lg" | "le" | "la" | "lF" | "lG" | "lE" | "lA" | "f" | "F" | "e" | "E" | "a"
| "A" | "g" | "G" => Datatype::Double,
"li" | "ld" | "lu" => Datatype::Long,
......
......@@ -475,6 +475,16 @@ pub enum Arg {
},
}
impl Arg {
/// Returns the data type field of an Arg object.
pub fn get_data_type(&self) -> Option<Datatype> {
match self {
Arg::Register { data_type, .. } => data_type.clone(),
Arg::Stack { data_type, .. } => data_type.clone(),
}
}
}
/// An extern symbol represents a funtion that is dynamically linked from another binary.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct ExternSymbol {
......
......@@ -90,10 +90,15 @@ pub fn parse_format_string_parameters(
.captures_iter(format_string)
.map(|cap| {
let data_type = Datatype::from(cap[1].to_string());
(
data_type.clone(),
datatype_properties.get_size_from_data_type(data_type),
)
let size = {
// Considers argument promotion for char type
if matches!(data_type, Datatype::Char) {
datatype_properties.get_size_from_data_type(Datatype::Integer)
} else {
datatype_properties.get_size_from_data_type(data_type.clone())
}
};
(data_type, size)
})
.collect();
......@@ -169,7 +174,7 @@ pub fn calculate_parameter_locations(
for (data_type, size) in parameters.iter() {
match data_type {
Datatype::Integer | Datatype::Pointer => {
Datatype::Integer | Datatype::Pointer | Datatype::Char => {
if integer_arg_register_count > 0 {
let register_name = calling_convention.integer_parameter_register
[calling_convention.integer_parameter_register.len()
......
......@@ -37,7 +37,7 @@ fn test_get_variable_parameters() {
output.push(Arg::Stack {
offset: 0,
size: ByteSize::new(4),
data_type: Some(Datatype::Integer),
data_type: Some(Datatype::Char),
});
output.push(Arg::Stack {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment