Skip to content

Commit 7fccc9c

Browse files
committed
Finished adding support for extern global variables declared in C, along with thread_local storage class
1 parent ef4ffdc commit 7fccc9c

File tree

9 files changed

+101
-20
lines changed

9 files changed

+101
-20
lines changed

Diff for: src/asg/expr/array_access.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
use super::Expr;
2-
use crate::asg::Type;
2+
use crate::asg::{Destination, Type};
3+
use derive_more::From;
34

45
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
56
pub struct ArrayAccess {
6-
pub subject: Expr,
7+
pub subject: ArrayDestination,
78
pub item_type: Type,
89
pub index: Expr,
910
}
11+
12+
#[derive(Clone, Debug, Hash, PartialEq, Eq, From)]
13+
pub enum ArrayDestination {
14+
Expr(Expr),
15+
Destination(Destination),
16+
}

Diff for: src/c/translation/function.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ pub fn declare_function(
2020
diagnostics: &Diagnostics,
2121
) -> Result<(), ParseError> {
2222
let source = declarator.source;
23-
let (name, return_type, storage_class, function_specifier) = get_name_and_type(
24-
ast_file,
25-
typedefs,
26-
declarator,
27-
declaration_specifiers,
28-
false,
29-
diagnostics,
30-
)?;
23+
let (name, return_type, storage_class, function_specifier, _is_thread_local) =
24+
get_name_and_type(
25+
ast_file,
26+
typedefs,
27+
declarator,
28+
declaration_specifiers,
29+
false,
30+
diagnostics,
31+
)?;
3132
let mut required = vec![];
3233

3334
if function_specifier.is_some() {
@@ -36,7 +37,7 @@ pub fn declare_function(
3637

3738
if has_parameters(parameter_type_list) {
3839
for param in parameter_type_list.parameter_declarations.iter() {
39-
let (name, ast_type, storage_class, function_specifier) = match &param.core {
40+
let (name, ast_type, storage_class, function_specifier, _) = match &param.core {
4041
ParameterDeclarationCore::Declarator(declarator) => get_name_and_type(
4142
ast_file,
4243
typedefs,

Diff for: src/c/translation/mod.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn declare_named_declaration(
2222
typedefs: &mut HashMap<String, CTypedef>,
2323
diagnostics: &Diagnostics,
2424
) -> Result<(), ParseError> {
25-
let (name, ast_type, storage_class, function_specifier) = get_name_and_type(
25+
let (name, ast_type, storage_class, function_specifier, is_thread_local) = get_name_and_type(
2626
ast_file,
2727
typedefs,
2828
declarator,
@@ -54,6 +54,28 @@ pub fn declare_named_declaration(
5454
return Ok(());
5555
}
5656

57+
if let Some(StorageClassSpecifier::Extern) = storage_class {
58+
if let Some(function_specifier) = function_specifier {
59+
diagnostics.push(WarningDiagnostic::new(
60+
format!(
61+
"Function specifier '{}' on functions is not respected yet",
62+
function_specifier.as_str()
63+
),
64+
declarator.source,
65+
));
66+
}
67+
68+
ast_file.global_variables.push(ast::GlobalVar {
69+
name,
70+
ast_type,
71+
source: declarator.source,
72+
is_foreign: true,
73+
is_thread_local,
74+
privacy: Privacy::Public,
75+
});
76+
return Ok(());
77+
}
78+
5779
todo!(
5880
"declare_named_declaration unimplemented for non-typedef - {:#?}",
5981
declarator

Diff for: src/c/translation/types/composite.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn make_composite(
5454
for member_declarator in member.member_declarators.iter() {
5555
match member_declarator {
5656
MemberDeclarator::Declarator(declarator) => {
57-
let (name, ast_type, storage_class, function_specifier) =
57+
let (name, ast_type, storage_class, function_specifier, _) =
5858
get_name_and_type(
5959
ast_file,
6060
typedefs,

Diff for: src/c/translation/types/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub struct TypeBase {
2828
pub ast_type: Type,
2929
pub storage_class: Option<StorageClassSpecifier>,
3030
pub function_specifier: Option<FunctionSpecifier>,
31+
pub is_thread_local: bool,
3132
}
3233

3334
#[derive(Debug)]
@@ -38,6 +39,7 @@ pub struct TypeBaseBuilder {
3839
pub concrete: Option<Type>,
3940
pub storage_class: Option<StorageClassSpecifier>,
4041
pub function_specifier: Option<FunctionSpecifier>,
42+
pub is_thread_local: bool,
4143
}
4244

4345
impl TypeBaseBuilder {
@@ -49,6 +51,7 @@ impl TypeBaseBuilder {
4951
concrete: None,
5052
storage_class: None,
5153
function_specifier: None,
54+
is_thread_local: false,
5255
}
5356
}
5457

@@ -71,6 +74,7 @@ impl TypeBaseBuilder {
7174
ast_type,
7275
storage_class: self.storage_class,
7376
function_specifier: self.function_specifier,
77+
is_thread_local: false,
7478
})
7579
}
7680

@@ -198,6 +202,7 @@ pub fn get_name_and_type(
198202
Type,
199203
Option<StorageClassSpecifier>,
200204
Option<FunctionSpecifier>,
205+
bool,
201206
),
202207
ParseError,
203208
> {
@@ -239,6 +244,7 @@ pub fn get_name_and_type(
239244
ast_type,
240245
type_base.storage_class,
241246
type_base.function_specifier,
247+
type_base.is_thread_local,
242248
))
243249
}
244250

@@ -266,7 +272,7 @@ fn get_name_and_decorators(
266272
for parameter in parameter_type_list.parameter_declarations.iter() {
267273
let (parameter_name, parameter_type) = match &parameter.core {
268274
ParameterDeclarationCore::Declarator(declarator) => {
269-
let (parameter_name, ast_type, _, _) = get_name_and_type(
275+
let (parameter_name, ast_type, _, _, _) = get_name_and_type(
270276
ast_file,
271277
typedefs,
272278
declarator,

Diff for: src/lower/expr/mod.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,15 @@ pub fn lower_expr(
267267
Ok(builder.push(ir::Instr::Load((member, ir_type))))
268268
}
269269
ExprKind::ArrayAccess(array_access) => {
270-
let subject = lower_expr(builder, ir_module, &array_access.subject, function, asg)?;
270+
let subject = match &array_access.subject {
271+
asg::ArrayDestination::Expr(subject) => {
272+
lower_expr(builder, ir_module, subject, function, asg)?
273+
}
274+
asg::ArrayDestination::Destination(subject) => {
275+
lower_destination(builder, ir_module, subject, function, asg)?
276+
}
277+
};
278+
271279
let index = lower_expr(builder, ir_module, &array_access.index, function, asg)?;
272280
let item_type = lower_type(ir_module, &builder.unpoly(&array_access.item_type)?, asg)?;
273281

@@ -602,8 +610,15 @@ pub fn lower_destination(
602610
}))
603611
}
604612
DestinationKind::ArrayAccess(array_access) => {
605-
let subject_pointer =
606-
lower_expr(builder, ir_module, &array_access.subject, function, asg)?;
613+
let subject_pointer = match &array_access.subject {
614+
asg::ArrayDestination::Expr(subject) => {
615+
lower_expr(builder, ir_module, subject, function, asg)?
616+
}
617+
asg::ArrayDestination::Destination(subject) => {
618+
lower_destination(builder, ir_module, subject, function, asg)?
619+
}
620+
};
621+
607622
let index = lower_expr(builder, ir_module, &array_access.index, function, asg)?;
608623
let item_type = lower_type(ir_module, &builder.unpoly(&array_access.item_type)?, asg)?;
609624

Diff for: src/resolve/expr/array_access.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
ast,
55
resolve::{
66
conform::to_default::conform_expr_to_default_or_error,
7+
destination::resolve_expr_to_destination,
78
error::{ResolveError, ResolveErrorKind},
89
Initialized,
910
},
@@ -42,8 +43,17 @@ pub fn resolve_array_access_expr(
4243
c_integer_assumptions,
4344
)?;
4445

45-
let item_type = match &subject.ty.kind {
46-
asg::TypeKind::Ptr(inner) => Ok((**inner).clone()),
46+
let (item_type, subject) = match &subject.ty.kind {
47+
asg::TypeKind::Ptr(inner) => {
48+
let item_type = (**inner).clone();
49+
let array_destination = subject.expr.into();
50+
Ok((item_type, array_destination))
51+
}
52+
asg::TypeKind::FixedArray(fixed_array) => {
53+
let item_type = fixed_array.inner.clone();
54+
let array_destination = resolve_expr_to_destination(subject)?.into();
55+
Ok((item_type, array_destination))
56+
}
4757
bad_type => Err(ResolveErrorKind::CannotAccessMemberOf {
4858
bad_type: bad_type.to_string(),
4959
}
@@ -62,7 +72,7 @@ pub fn resolve_array_access_expr(
6272
item_type.clone(),
6373
asg::Expr::new(
6474
asg::ExprKind::ArrayAccess(Box::new(asg::ArrayAccess {
65-
subject: subject.expr,
75+
subject,
6676
index: index.expr,
6777
item_type,
6878
})),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
pragma => adept("3.0")
3+
4+
#[foreign]
5+
func printf(format ptr#char, ...) int
6+
7+
func main {
8+
printf(c"errno = %s\n", strerror(errno))
9+
}
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
#ifndef _C_ERRNO_H_INCLUDED
3+
#define _C_ERRNO_H_INCLUDED
4+
5+
thread_local extern int errno;
6+
7+
char *strerror(int errnum);
8+
9+
#endif // _C_ERRNO_H_INCLUDED
10+

0 commit comments

Comments
 (0)