Skip to content

Commit c25443a

Browse files
committed
Implement @extern
A more targeted version of --allow-undefined
1 parent f3bff3d commit c25443a

File tree

9 files changed

+57
-14
lines changed

9 files changed

+57
-14
lines changed

src/frontend/Environment.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type info =
2121
; kind:
2222
[ `Variable of varinfo
2323
| `UserDeclared of Location_span.t
24+
| `UserExtern of Location_span.t
2425
| `StanMath
2526
| `UserDefined ] }
2627
[@@deriving sexp]

src/frontend/Environment.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type info =
2121
; kind:
2222
[ `Variable of varinfo
2323
| `UserDeclared of Location_span.t
24+
| `UserExtern of Location_span.t
2425
| `StanMath
2526
| `UserDefined ] }
2627

@@ -37,6 +38,7 @@ val add :
3738
-> string
3839
-> Middle.UnsizedType.t
3940
-> [ `UserDeclared of Location_span.t
41+
| `UserExtern of Location_span.t
4042
| `StanMath
4143
| `UserDefined
4244
| `Variable of varinfo ]

src/frontend/Typechecker.ml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,14 +292,14 @@ let check_id cf loc tenv id =
292292
Semantic_error.invalid_unnormalized_fn loc |> error
293293
| {kind= `Variable {origin; _}; type_} :: _ ->
294294
(calculate_autodifftype cf origin type_, type_)
295-
| { kind= `UserDefined | `UserDeclared _
295+
| { kind= `UserDefined | `UserExtern _ | `UserDeclared _
296296
; type_= UFun (args, rt, FnLpdf _, mem_pattern) }
297297
:: _ ->
298298
let type_ =
299299
UnsizedType.UFun
300300
(args, rt, Fun_kind.suffix_from_name id.name, mem_pattern) in
301301
(calculate_autodifftype cf Functions type_, type_)
302-
| {kind= `UserDefined | `UserDeclared _; type_} :: _ ->
302+
| {kind= `UserDefined | `UserExtern _ | `UserDeclared _; type_} :: _ ->
303303
(calculate_autodifftype cf Functions type_, type_)
304304

305305
let check_variable cf loc tenv id =
@@ -1177,7 +1177,8 @@ let verify_assignable_id loc cf tenv assign_id =
11771177
| {kind= `Variable {origin; global; readonly}; _} :: _ ->
11781178
(origin, global, readonly)
11791179
| {kind= `StanMath; _} :: _ -> (MathLibrary, true, false)
1180-
| {kind= `UserDefined | `UserDeclared _; _} :: _ -> (Functions, true, false)
1180+
| {kind= `UserDefined | `UserDeclared _ | `UserExtern _; _} :: _ ->
1181+
(Functions, true, false)
11811182
| _ ->
11821183
Semantic_error.ident_not_in_scope loc assign_id.name
11831184
(Env.nearest_ident tenv assign_id.name)
@@ -1727,11 +1728,13 @@ and verify_fundef_overloaded loc tenv id arg_tys rt =
17271728
verify_unique_signature tenv loc id arg_tys rt;
17281729
verify_name_fresh tenv id ~is_udf:true
17291730

1730-
and get_fn_decl_or_defn loc tenv id arg_tys rt body =
1731+
and get_fn_decl_or_defn loc tenv id arg_tys rt body annotations =
17311732
match body with
17321733
| {stmt= Skip; _} ->
17331734
if exists_matching_fn_declared tenv id arg_tys rt then
17341735
Semantic_error.fn_decl_exists loc id.name |> error
1736+
else if List.mem annotations "extern" ~equal:String.equal then
1737+
`UserExtern id.id_loc
17351738
else `UserDeclared id.id_loc
17361739
| _ -> `UserDefined
17371740

@@ -1909,13 +1912,13 @@ let add_userdefined_functions tenv stmts_opt =
19091912
| Some {stmts; _} ->
19101913
let f tenv (s : Ast.untyped_statement) =
19111914
match s with
1912-
| { stmt= FunDef {returntype; funname; arguments; body; annotations= _}
1915+
| { stmt= FunDef {returntype; funname; arguments; body; annotations}
19131916
; smeta= {loc} } ->
19141917
let arg_types = Ast.type_of_arguments arguments in
19151918
verify_fundef_overloaded loc tenv funname arg_types returntype;
19161919
let defined =
19171920
get_fn_decl_or_defn loc tenv funname arg_types returntype body
1918-
in
1921+
annotations in
19191922
add_function tenv funname.name
19201923
(UFun
19211924
( arg_types

src/stan_math_backend/Transform_Mir.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ let map_prog_stmt_lists f (p : ('a, 'b, 'c) Program.t) =
10121012
; transform_inits= f p.transform_inits
10131013
; unconstrain_array= f p.unconstrain_array }
10141014

1015-
let recognized_annotation _ = false
1015+
let recognized_annotation a = a = "extern"
10161016

10171017
let trans_prog (p : Program.Typed.t) =
10181018
(* name mangling of c++ keywords*)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
functions {
2+
@extern real foo(int x, int y);
3+
real foo(int x, int y){
4+
return 1.0;
5+
}
6+
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
functions {
2+
@extern real foo(int x, int y);
3+
real foo(int x, int y);
4+
}

test/integration/bad/function-signatures/overloading/stanc.expected

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
$ ../../../../../../install/default/bin/stanc define_extern1.stan
2+
Semantic error in 'define_extern1.stan', line 2, column 33 to line 5, column 3:
3+
-------------------------------------------------
4+
1: functions {
5+
2: @extern real foo(int x, int y);
6+
^
7+
3: real foo(int x, int y){
8+
4: return 1.0;
9+
-------------------------------------------------
10+
11+
Function 'foo' has already been declared for signature (int, int) => real
12+
$ ../../../../../../install/default/bin/stanc define_extern2.stan
13+
Semantic error in 'define_extern2.stan', line 2, column 33 to line 3, column 25:
14+
-------------------------------------------------
15+
1: functions {
16+
2: @extern real foo(int x, int y);
17+
^
18+
3: real foo(int x, int y);
19+
4: }
20+
-------------------------------------------------
21+
22+
Function 'foo' has already been declared for signature (int, int) => real
123
$ ../../../../../../install/default/bin/stanc no_minimum_dae.stan
224
Semantic error in 'no_minimum_dae.stan', line 38, column 12 to column 59:
325
-------------------------------------------------

test/integration/good/lang/good_annotations.stan

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
functions {
2+
@extern real foo(int x, int y);
3+
24
@foo @biz void bar(int x, int y, int z, int w, int a, int b, int d, int e, int f){
35
print(x);
46
}

test/integration/good/lang/pretty.expected

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ model {
1717

1818
$ ../../../../../install/default/bin/stanc --auto-format good_annotations.stan
1919
functions {
20+
@extern real foo(int x, int y);
21+
2022
@foo
2123
@biz
2224
void bar(int x, int y, int z, int w, int a, int b, int d, int e, int f) {
@@ -35,19 +37,19 @@ generated quantities {
3537
matrix[34, 10000] a_bit_too_long = rep_matrix(1, 34, 10000);
3638
}
3739

38-
Warning in 'good_annotations.stan', line 2, column 17: Unknown annotation
40+
Warning in 'good_annotations.stan', line 4, column 17: Unknown annotation
3941
'foo' will be ignored by the compiler
40-
Warning in 'good_annotations.stan', line 2, column 17: Unknown annotation
42+
Warning in 'good_annotations.stan', line 4, column 17: Unknown annotation
4143
'biz' will be ignored by the compiler
42-
Warning in 'good_annotations.stan', line 7, column 19: Unknown annotation
44+
Warning in 'good_annotations.stan', line 9, column 19: Unknown annotation
4345
'baz' will be ignored by the compiler
44-
Warning in 'good_annotations.stan', line 12, column 89: Unknown annotation
46+
Warning in 'good_annotations.stan', line 14, column 89: Unknown annotation
4547
'bar' will be ignored by the compiler
46-
Warning in 'good_annotations.stan', line 12, column 89: Unknown annotation
48+
Warning in 'good_annotations.stan', line 14, column 89: Unknown annotation
4749
'baz' will be ignored by the compiler
48-
Warning in 'good_annotations.stan', line 12, column 89: Unknown annotation
50+
Warning in 'good_annotations.stan', line 14, column 89: Unknown annotation
4951
'flux' will be ignored by the compiler
50-
Warning in 'good_annotations.stan', line 12, column 89: Unknown annotation
52+
Warning in 'good_annotations.stan', line 14, column 89: Unknown annotation
5153
'really_extra_long_now' will be ignored by the compiler
5254
$ ../../../../../install/default/bin/stanc --auto-format good_const.stan
5355
transformed data {

0 commit comments

Comments
 (0)