Skip to content

Commit 6a0285c

Browse files
committed
Implemented type/expression differentiation for C sizeof
1 parent b1131bd commit 6a0285c

File tree

5 files changed

+63
-15
lines changed

5 files changed

+63
-15
lines changed

src/c/ast/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ impl TypeSpecifierQualifier {
262262
pub struct SpecifierQualifierList {
263263
pub attributes: Vec<Attribute>,
264264
pub type_specifier_qualifiers: Vec<TypeSpecifierQualifier>,
265+
pub source: Source,
265266
}
266267

267268
#[derive(Clone, Debug)]
@@ -317,6 +318,7 @@ pub enum AlignmentSpecifierKind {
317318
pub struct DeclarationSpecifiers {
318319
pub specifiers: Vec<DeclarationSpecifier>,
319320
pub attributes: Vec<Attribute>,
321+
pub source: Source,
320322
}
321323

322324
impl From<&SpecifierQualifierList> for DeclarationSpecifiers {
@@ -330,6 +332,7 @@ impl From<&SpecifierQualifierList> for DeclarationSpecifiers {
330332
Self {
331333
attributes: value.attributes.clone(),
332334
specifiers,
335+
source: value.source,
333336
}
334337
}
335338
}

src/c/parser/expr.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ use crate::{
88
parser::speculate::speculate,
99
punctuator::Punctuator,
1010
token::CTokenKind,
11-
translate::TranslateCtx,
11+
translate::{types::get_type, TranslateCtx},
1212
},
1313
source_files::Source,
1414
};
15-
use ignore::types::TypesBuilder;
1615

1716
// Implements expression parsing for the C parser
1817
impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
@@ -269,12 +268,21 @@ impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
269268
CTokenKind::SizeofKeyword => {
270269
self.input.advance();
271270

272-
#[allow(unused)]
273271
if let Ok(type_name) = speculate!(self.input, self.parse_type_in_parens()) {
274-
let ctx =
272+
let mut ctx =
275273
TranslateCtx::new(&mut self.ast_file, &mut self.typedefs, self.diagnostics);
276-
let mut type_builder = TypesBuilder::new();
277-
return todo!("handle parsed sizeof(type)");
274+
let specifier_qualifiers = &type_name.specifier_qualifiers;
275+
276+
let ty = get_type(
277+
&mut ctx,
278+
type_name.abstract_declarator.as_ref(),
279+
&specifier_qualifiers.into(),
280+
false,
281+
);
282+
283+
if let Ok(ty) = ty {
284+
return todo!("handle parsed sizeof(type) - {:?}", ty);
285+
}
278286
}
279287

280288
let _inner = self.parse_expr_primary_base()?;

src/c/parser/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
187187
}
188188

189189
fn parse_declaration_specifiers(&mut self) -> Result<DeclarationSpecifiers, ParseError> {
190+
let source = self.here();
190191
let mut specifiers = vec![];
191192

192193
while let Ok(specifier) = speculate!(self.input, self.parse_declaration_specifier()) {
@@ -197,6 +198,7 @@ impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
197198
Ok(DeclarationSpecifiers {
198199
specifiers,
199200
attributes,
201+
source,
200202
})
201203
}
202204

@@ -748,6 +750,7 @@ impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
748750
}
749751

750752
fn parse_specifier_qualifier_list(&mut self) -> Result<SpecifierQualifierList, ParseError> {
753+
let source = self.here();
751754
let mut type_specifier_qualifiers = vec![];
752755

753756
while let Ok(qualifier) = speculate!(self.input, self.parse_type_specifier_qualifier()) {
@@ -759,6 +762,7 @@ impl<'input, 'diagnostics> Parser<'input, 'diagnostics> {
759762
Ok(SpecifierQualifierList {
760763
attributes,
761764
type_specifier_qualifiers,
765+
source,
762766
})
763767
}
764768

src/c/translate/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod eval;
22
mod expr;
33
mod function;
44
mod parameters;
5-
mod types;
5+
pub mod types;
66

77
use self::types::get_name_and_type;
88
pub use self::{expr::translate_expr, function::declare_function};

src/c/translate/types/mod.rs

+41-8
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,47 @@ pub fn get_name_and_type(
207207
for_parameter: bool,
208208
) -> Result<DeclaratorInfo, ParseError> {
209209
let (name, decorators) = get_name_and_decorators(ctx, declarator)?;
210-
let type_base = get_type_base(ctx, declaration_specifiers, declarator.source)?;
210+
let type_base = get_type_base(ctx, declaration_specifiers, declaration_specifiers.source)?;
211+
let ast_type = apply_decorators(ctx, &decorators, type_base.ast_type, for_parameter)?;
211212

212-
let mut ast_type = type_base.ast_type;
213+
Ok(DeclaratorInfo {
214+
name,
215+
ast_type,
216+
specifiers: type_base.specifiers,
217+
})
218+
}
219+
220+
#[derive(Clone, Debug)]
221+
pub struct AbstractDeclaratorInfo {
222+
pub ast_type: Type,
223+
pub specifiers: TypeBaseSpecifiers,
224+
}
225+
226+
pub fn get_type(
227+
ctx: &mut TranslateCtx,
228+
abstract_declarator: Option<&AbstractDeclarator>,
229+
declaration_specifiers: &DeclarationSpecifiers,
230+
for_parameter: bool,
231+
) -> Result<AbstractDeclaratorInfo, ParseError> {
232+
let decorators = abstract_declarator
233+
.map(|abstract_declarator| get_decorators(ctx, abstract_declarator))
234+
.transpose()?
235+
.unwrap_or_default();
236+
let type_base = get_type_base(ctx, declaration_specifiers, declaration_specifiers.source)?;
237+
let ast_type = apply_decorators(ctx, &decorators, type_base.ast_type, for_parameter)?;
238+
239+
Ok(AbstractDeclaratorInfo {
240+
ast_type,
241+
specifiers: type_base.specifiers,
242+
})
243+
}
213244

245+
fn apply_decorators(
246+
ctx: &mut TranslateCtx,
247+
decorators: &Decorators,
248+
mut ast_type: Type,
249+
for_parameter: bool,
250+
) -> Result<Type, ParseError> {
214251
for decorator in decorators.iter() {
215252
match decorator {
216253
Decorator::Pointer(pointer) => {
@@ -223,14 +260,10 @@ pub fn get_name_and_type(
223260
Decorator::Function(function) => {
224261
ast_type = decorate_function(ast_type, function, decorator.source())?;
225262
}
226-
}
263+
};
227264
}
228265

229-
Ok(DeclaratorInfo {
230-
name,
231-
ast_type,
232-
specifiers: type_base.specifiers,
233-
})
266+
Ok(ast_type)
234267
}
235268

236269
fn get_name_and_decorators(

0 commit comments

Comments
 (0)