瀏覽代碼

Provide method for accessing accounts on Solana (#618)

Introduce AccountInfo struct and tx.accounts builtin for accessing the accounts in the transaction

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 3 年之前
父節點
當前提交
8600dd550e
共有 64 個文件被更改,包括 1852 次插入1276 次删除
  1. 5 0
      CHANGELOG.md
  2. 1 1
      Cargo.toml
  3. 31 0
      docs/language.rst
  4. 23 21
      src/bin/doc/mod.rs
  5. 9 7
      src/bin/languageserver/mod.rs
  6. 2 0
      src/codegen/expression.rs
  7. 1 0
      src/codegen/statements.rs
  8. 36 20
      src/emit/mod.rs
  9. 177 0
      src/emit/solana.rs
  10. 1 1
      src/emit/substrate.rs
  11. 2 3
      src/linker/mod.rs
  12. 3 1
      src/sema/ast.rs
  13. 727 709
      src/sema/builtin.rs
  14. 1 0
      src/sema/contracts.rs
  15. 19 17
      src/sema/dotgraphviz.rs
  16. 66 25
      src/sema/expression.rs
  17. 33 8
      src/sema/functions.rs
  18. 8 1
      src/sema/mod.rs
  19. 11 1
      src/sema/statements.rs
  20. 32 4
      src/sema/types.rs
  21. 11 0
      src/sema/variables.rs
  22. 2 2
      tests/contract_testcases/solana/accessor/constant.dot
  23. 6 6
      tests/contract_testcases/solana/accessor/constant_01.dot
  24. 28 0
      tests/contract_testcases/solana/account_info.dot
  25. 22 0
      tests/contract_testcases/solana/account_info.sol
  26. 2 2
      tests/contract_testcases/solana/assembly/parse.dot
  27. 2 2
      tests/contract_testcases/solana/call/calltys.dot
  28. 2 2
      tests/contract_testcases/solana/call/calltys_01.dot
  29. 2 2
      tests/contract_testcases/solana/call/calltys_02.dot
  30. 9 9
      tests/contract_testcases/solana/constant/not_constant.dot
  31. 9 9
      tests/contract_testcases/solana/constant/not_constant_01.dot
  32. 6 6
      tests/contract_testcases/solana/create_contract/syntax.dot
  33. 6 6
      tests/contract_testcases/solana/create_contract/syntax_01.dot
  34. 200 200
      tests/contract_testcases/solana/doccomments_everywhere.dot
  35. 14 14
      tests/contract_testcases/solana/event.dot
  36. 20 20
      tests/contract_testcases/solana/expressions/bytes32_0.dot
  37. 2 2
      tests/contract_testcases/solana/expressions/bytes32_0_01.dot
  38. 52 52
      tests/contract_testcases/solana/expressions/bytes32_0_02.dot
  39. 5 5
      tests/contract_testcases/solana/expressions/const_in_type.dot
  40. 19 19
      tests/contract_testcases/solana/expressions/contract_compare.dot
  41. 19 19
      tests/contract_testcases/solana/expressions/contract_no_init.dot
  42. 2 2
      tests/contract_testcases/solana/expressions/interfaceid.dot
  43. 2 2
      tests/contract_testcases/solana/expressions/pushpop.dot
  44. 2 2
      tests/contract_testcases/solana/expressions/pushpop_01.dot
  45. 6 6
      tests/contract_testcases/solana/expressions/selector_in_free_function.dot
  46. 10 10
      tests/contract_testcases/solana/expressions/selector_in_free_function_01.dot
  47. 9 9
      tests/contract_testcases/solana/expressions/selector_in_free_function_02.dot
  48. 5 5
      tests/contract_testcases/solana/expressions/slice.dot
  49. 2 2
      tests/contract_testcases/solana/expressions/tx.dot
  50. 2 2
      tests/contract_testcases/solana/expressions/tx_01.dot
  51. 2 2
      tests/contract_testcases/solana/hash/constants_hash_tests.dot
  52. 2 2
      tests/contract_testcases/solana/hash/constants_hash_tests_01.dot
  53. 2 2
      tests/contract_testcases/solana/rational/rational.dot
  54. 4 4
      tests/contract_testcases/solana/returns/return_err.dot
  55. 4 4
      tests/contract_testcases/solana/returns/return_err_01.dot
  56. 12 12
      tests/contract_testcases/solana/returns/return_err_02.dot
  57. 10 10
      tests/contract_testcases/solana/returns/return_err_03.dot
  58. 2 2
      tests/contract_testcases/solana/returns/return_err_04.dot
  59. 16 0
      tests/contract_testcases/substrate/account_info.dot
  60. 6 0
      tests/contract_testcases/substrate/account_info.sol
  61. 1 1
      tests/contract_testcases/substrate/function_types/decls_07.dot
  62. 1 1
      tests/solana.rs
  63. 123 0
      tests/solana_tests/account_info.rs
  64. 1 0
      tests/solana_tests/mod.rs

+ 5 - 0
CHANGELOG.md

@@ -4,9 +4,14 @@ will be documented here.
 
 ## [Unreleased]
 
+### Added
+- On Solana, the accounts that were passed into the transactions are listed in
+  the `tx.accounts` builtin. There is also a builtin struct `AccountInfo`
+
 ### Changed
 - Solang now uses LLVM 13.0, based on the [Solana LLVM tree](https://github.com/solana-labs/llvm-project/)
 
+
 ## [0.1.9]
 
 ### Added

+ 1 - 1
Cargo.toml

@@ -20,7 +20,6 @@ num-traits = "0.2"
 num-derive = "0.3"
 parity-wasm = "0.42"
 clap = "3.0"
-lazy_static = "1.4"
 hex = "0.4"
 tiny-keccak = { version = "2.0", features = ["keccak"] }
 serde_json = "1.0"
@@ -43,6 +42,7 @@ funty = "=1.1.0"
 itertools = "0.10"
 num-rational = "0.4"
 indexmap = "1.7"
+once_cell = "1.9"
 solang-parser = { path = "solang-parser", version = "0.1.1" }
 
 [dev-dependencies]

+ 31 - 0
docs/language.rst

@@ -2990,6 +2990,37 @@ uint128 ``tx.gasprice(uint64 gas)``
 address ``tx.origin``
     The address that started this transaction. Not available on Parity Substrate or Solana.
 
+AccountInfo[] ``tx.accounts``
+    Only available on Solana.
+
+    The account info of all the accounts passed into the transaction. ``AccountInfo`` is a builtin
+    structure with the following fields:
+
+    address ``key``
+        The address (or public key) of the account
+
+    uint64 ``lamports``
+        The lamports of the accounts. This field can be modified, however the lamports need to be
+        balanced for all accounts by the end of the transaction.
+
+    bytes ``data```
+        The account data. This field can be modified, but use with caution.
+
+    address ``owner``
+        The program that owns this account
+
+    uint64 ``rent_epoch``
+        The next epoch when rent is due.
+
+    bool ``is_signer``
+        Did this account sign the transaction
+
+    bool ``is_writable``
+        Is this account writable in this transaction
+
+    bool ``executable``
+        Is this account a program
+
 
 ``block`` properties
 ++++++++++++++++++++++

+ 23 - 21
src/bin/doc/mod.rs

@@ -195,31 +195,33 @@ pub fn generate_docs(outdir: &str, files: &[ast::Namespace], verbose: bool) {
 
         // structs
         for struct_decl in &file.structs {
-            if top.structs.iter().any(|e| e.loc == struct_decl.loc) {
-                continue;
-            }
+            if let Some(loc) = struct_decl.loc {
+                if top.structs.iter().any(|e| e.loc == loc) {
+                    continue;
+                }
 
-            let mut field = Vec::new();
+                let mut field = Vec::new();
 
-            for (i, f) in struct_decl.fields.iter().enumerate() {
-                field.push(Field {
-                    name: &f.name,
-                    ty: f.ty.to_string(file),
-                    indexed: false,
-                    doc: get_tag_no("param", i, &struct_decl.tags),
+                for (i, f) in struct_decl.fields.iter().enumerate() {
+                    field.push(Field {
+                        name: &f.name,
+                        ty: f.ty.to_string(file),
+                        indexed: false,
+                        doc: get_tag_no("param", i, &struct_decl.tags),
+                    });
+                }
+
+                top.structs.push(StructDecl {
+                    name: &struct_decl.name,
+                    contract: struct_decl.contract.as_deref(),
+                    title: get_tag("title", &struct_decl.tags),
+                    notice: get_tag("notice", &struct_decl.tags),
+                    author: get_tag("author", &struct_decl.tags),
+                    dev: get_tag("dev", &struct_decl.tags),
+                    loc,
+                    field,
                 });
             }
-
-            top.structs.push(StructDecl {
-                name: &struct_decl.name,
-                contract: struct_decl.contract.as_deref(),
-                title: get_tag("title", &struct_decl.tags),
-                notice: get_tag("notice", &struct_decl.tags),
-                author: get_tag("author", &struct_decl.tags),
-                dev: get_tag("dev", &struct_decl.tags),
-                loc: struct_decl.loc,
-                field,
-            });
         }
 
         // enum

+ 9 - 7
src/bin/languageserver/mod.rs

@@ -152,11 +152,11 @@ impl SolangServer {
         let prot = get_prototype(*bltn);
 
         if let Some(protval) = prot {
-            for ret in protval.ret {
+            for ret in &protval.ret {
                 msg = format!("{} {}", msg, SolangServer::expanded_ty(ret, ns));
             }
             msg = format!("{} {} (", msg, protval.name);
-            for arg in protval.args {
+            for arg in &protval.args {
                 msg = format!("{}{}", msg, SolangServer::expanded_ty(arg, ns));
             }
             msg = format!("{}): {}", msg, protval.doc);
@@ -842,12 +842,14 @@ impl SolangServer {
         }
 
         for strct in &ns.structs {
-            for filds in &strct.fields {
-                SolangServer::construct_strct(filds, lookup_tbl, ns);
-            }
+            if let Some(loc) = &strct.loc {
+                for filds in &strct.fields {
+                    SolangServer::construct_strct(filds, lookup_tbl, ns);
+                }
 
-            let msg_tg = render(&strct.tags[..]);
-            lookup_tbl.push((strct.loc.1, (strct.loc.1 + strct.name.len()), msg_tg));
+                let msg_tg = render(&strct.tags[..]);
+                lookup_tbl.push((loc.1, (loc.1 + strct.name.len()), msg_tg));
+            }
         }
 
         for fnc in &ns.functions {

+ 2 - 0
src/codegen/expression.rs

@@ -2093,6 +2093,7 @@ pub fn emit_function_call(
                             name: String::new(),
                             name_loc: None,
                             indexed: false,
+                            readonly: false,
                         });
                     }
 
@@ -2142,6 +2143,7 @@ pub fn emit_function_call(
                             ty: ty.clone(),
                             ty_loc: *loc,
                             indexed: false,
+                            readonly: false,
                         })
                         .collect(),
                     data,

+ 1 - 0
src/codegen/statements.rs

@@ -1109,6 +1109,7 @@ fn try_catch(
                             name_loc: None,
                             loc: pt::Loc(0, 0, 0),
                             indexed: false,
+                            readonly: false,
                         })
                         .collect();
 

+ 36 - 20
src/emit/mod.rs

@@ -36,6 +36,7 @@ mod ewasm;
 mod loop_builder;
 mod solana;
 mod substrate;
+use once_cell::sync::OnceCell;
 
 use crate::{
     codegen::{
@@ -45,12 +46,7 @@ use crate::{
     linker::link,
 };
 
-lazy_static::lazy_static! {
-    static ref LLVM_INIT: () = {
-        inkwell::targets::Target::initialize_webassembly(&Default::default());
-        inkwell::targets::Target::initialize_bpf(&Default::default());
-    };
-}
+static LLVM_INIT: OnceCell<()> = OnceCell::new();
 
 #[derive(Clone)]
 pub struct Variable<'a> {
@@ -2336,6 +2332,19 @@ pub trait TargetRuntime<'a> {
 
                     self.storage_subscript(bin, function, ty, array, index, ns)
                         .into()
+                } else if elem_ty.is_builtin(ns) {
+                    let array = self
+                        .expression(bin, a, vartab, function, ns)
+                        .into_pointer_value();
+                    let index = self
+                        .expression(bin, i, vartab, function, ns)
+                        .into_int_value();
+
+                    unsafe {
+                        bin.builder
+                            .build_gep(array, &[index], "account_info")
+                            .into()
+                    }
                 } else if ty.is_dynamic_memory() {
                     let array = self.expression(bin, a, vartab, function, ns);
 
@@ -2391,23 +2400,18 @@ pub trait TargetRuntime<'a> {
                     }
                 }
             }
+            Expression::StructMember(_, _, a, _) if a.ty().is_builtin(ns) => {
+                self.builtin(bin, e, vartab, function, ns)
+            }
             Expression::StructMember(_, _, a, i) => {
                 let struct_ptr = self
                     .expression(bin, a, vartab, function, ns)
                     .into_pointer_value();
 
-                unsafe {
-                    bin.builder
-                        .build_gep(
-                            struct_ptr,
-                            &[
-                                bin.context.i32_type().const_zero(),
-                                bin.context.i32_type().const_int(*i as u64, false),
-                            ],
-                            "struct member",
-                        )
-                        .into()
-                }
+                bin.builder
+                    .build_struct_gep(struct_ptr, *i as u32, "struct member")
+                    .unwrap()
+                    .into()
             }
             Expression::Ternary(_, _, c, l, r) => {
                 let cond = self
@@ -2546,7 +2550,9 @@ pub trait TargetRuntime<'a> {
                     bin.vector_new(size, elem_size, init.as_ref()).into()
                 }
             }
-            Expression::Builtin(_, _, Builtin::ArrayLength, args) => {
+            Expression::Builtin(_, _, Builtin::ArrayLength, args)
+                if !args[0].ty().array_deref().is_builtin(ns) =>
+            {
                 let array = self.expression(bin, &args[0], vartab, function, ns);
 
                 bin.vector_len(array).into()
@@ -5744,7 +5750,10 @@ impl<'a> Binary<'a> {
         math_overflow_check: bool,
         runtime: Option<Box<Binary<'a>>>,
     ) -> Self {
-        lazy_static::initialize(&LLVM_INIT);
+        LLVM_INIT.get_or_init(|| {
+            inkwell::targets::Target::initialize_webassembly(&Default::default());
+            inkwell::targets::Target::initialize_bpf(&Default::default());
+        });
 
         let triple = target.llvm_target_triple();
         let module = context.create_module(name);
@@ -6251,6 +6260,13 @@ impl<'a> Binary<'a> {
 
     /// Return the llvm type for the resolved type.
     fn llvm_type(&self, ty: &ast::Type, ns: &ast::Namespace) -> BasicTypeEnum<'a> {
+        if ty.is_builtin(ns) {
+            return self
+                .module
+                .get_struct_type("struct.SolAccountInfo")
+                .unwrap()
+                .into();
+        }
         match ty {
             ast::Type::Bool => BasicTypeEnum::IntType(self.context.bool_type()),
             ast::Type::Int(n) | ast::Type::Uint(n) => {

+ 177 - 0
src/emit/solana.rs

@@ -1435,6 +1435,145 @@ impl SolanaTarget {
 
         binary.builder.build_load(offset, "offset").into_int_value()
     }
+
+    /// AccountInfo struct member
+    fn account_info_member<'b>(
+        &self,
+        binary: &Binary<'b>,
+        function: FunctionValue<'b>,
+        account_info: PointerValue<'b>,
+        member: usize,
+        ns: &ast::Namespace,
+    ) -> BasicValueEnum<'b> {
+        match member {
+            // key
+            0 => {
+                let key = binary
+                    .builder
+                    .build_load(
+                        binary
+                            .builder
+                            .build_struct_gep(account_info, 0, "key")
+                            .unwrap(),
+                        "key",
+                    )
+                    .into_pointer_value();
+
+                binary.builder.build_load(
+                    binary.builder.build_pointer_cast(
+                        key,
+                        binary.address_type(ns).ptr_type(AddressSpace::Generic),
+                        "address",
+                    ),
+                    "key",
+                )
+            }
+            // lamports
+            1 => binary.builder.build_load(
+                binary
+                    .builder
+                    .build_struct_gep(account_info, 1, "lamports")
+                    .unwrap(),
+                "lamports",
+            ),
+            // data
+            2 => {
+                let data_len = binary.builder.build_int_truncate(
+                    binary
+                        .builder
+                        .build_load(
+                            binary
+                                .builder
+                                .build_struct_gep(account_info, 2, "data_len")
+                                .unwrap(),
+                            "data_len",
+                        )
+                        .into_int_value(),
+                    binary.context.i32_type(),
+                    "data_len",
+                );
+
+                let data = binary.builder.build_load(
+                    binary
+                        .builder
+                        .build_struct_gep(account_info, 3, "data")
+                        .unwrap(),
+                    "data",
+                );
+
+                let slice_alloca = binary.build_alloca(
+                    function,
+                    binary.llvm_type(&ast::Type::Slice, ns),
+                    "slice_alloca",
+                );
+                let data_elem = binary
+                    .builder
+                    .build_struct_gep(slice_alloca, 0, "data")
+                    .unwrap();
+                binary.builder.build_store(data_elem, data);
+                let data_len_elem = binary
+                    .builder
+                    .build_struct_gep(slice_alloca, 1, "data_len")
+                    .unwrap();
+                binary.builder.build_store(data_len_elem, data_len);
+
+                binary.builder.build_load(slice_alloca, "data_slice")
+            }
+            // owner
+            3 => {
+                let owner = binary
+                    .builder
+                    .build_load(
+                        binary
+                            .builder
+                            .build_struct_gep(account_info, 4, "owner")
+                            .unwrap(),
+                        "owner",
+                    )
+                    .into_pointer_value();
+
+                binary.builder.build_load(
+                    binary.builder.build_pointer_cast(
+                        owner,
+                        binary.address_type(ns).ptr_type(AddressSpace::Generic),
+                        "address",
+                    ),
+                    "owner",
+                )
+            }
+            // rent epoch
+            4 => {
+                let rent_epoch = binary
+                    .builder
+                    .build_struct_gep(account_info, 5, "rent_epoch")
+                    .unwrap();
+
+                binary.builder.build_load(rent_epoch, "rent_epoch")
+            }
+            // remaining fields are bool
+            _ => {
+                let bool_field = binary
+                    .builder
+                    .build_struct_gep(account_info, member as u32 + 1, "bool_field")
+                    .unwrap();
+
+                let value = binary
+                    .builder
+                    .build_load(bool_field, "bool_field")
+                    .into_int_value();
+
+                binary
+                    .builder
+                    .build_int_compare(
+                        IntPredicate::NE,
+                        value,
+                        value.get_type().const_zero(),
+                        "is_non_zero",
+                    )
+                    .into()
+            }
+        }
+    }
 }
 
 impl<'a> TargetRuntime<'a> for SolanaTarget {
@@ -3445,6 +3584,44 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
                 binary.builder.build_load(lamport, "lamport")
             }
+            ast::Expression::Builtin(_, _, ast::Builtin::Accounts, _) => {
+                let parameters = self.sol_parameters(binary);
+
+                unsafe {
+                    binary.builder.build_gep(
+                        parameters,
+                        &[
+                            binary.context.i32_type().const_int(0, false),
+                            binary.context.i32_type().const_int(0, false),
+                            binary.context.i32_type().const_int(0, false),
+                        ],
+                        "accounts",
+                    )
+                }
+                .into()
+            }
+            ast::Expression::Builtin(_, _, ast::Builtin::ArrayLength, _) => {
+                let parameters = self.sol_parameters(binary);
+
+                let ka_num = binary
+                    .builder
+                    .build_struct_gep(parameters, 1, "ka_num")
+                    .unwrap();
+
+                let ka_num = binary.builder.build_load(ka_num, "ka_num").into_int_value();
+
+                binary
+                    .builder
+                    .build_int_truncate(ka_num, binary.context.i32_type(), "ka_num_32bits")
+                    .into()
+            }
+            ast::Expression::StructMember(_, _, a, member) => {
+                let account_info = self
+                    .expression(binary, a, vartab, function, ns)
+                    .into_pointer_value();
+
+                self.account_info_member(binary, function, account_info, *member, ns)
+            }
             _ => unimplemented!(),
         }
     }

+ 1 - 1
src/emit/substrate.rs

@@ -4470,7 +4470,7 @@ impl<'a> TargetRuntime<'a> for SubstrateTarget {
                     "balance",
                 )
             }
-            _ => unimplemented!(),
+            _ => unreachable!("{:?}", expr),
         }
     }
 }

+ 2 - 3
src/linker/mod.rs

@@ -2,12 +2,11 @@ mod bpf;
 mod wasm;
 
 use crate::Target;
+use once_cell::sync::Lazy;
 use std::ffi::CString;
 use std::sync::Mutex;
 
-lazy_static::lazy_static! {
-    static ref LINKER_MUTEX: Mutex<i32> = Mutex::new(0i32);
-}
+static LINKER_MUTEX: Lazy<Mutex<i32>> = Lazy::new(|| Mutex::new(0i32));
 
 /// Take an object file and turn it into a final linked binary ready for deployment
 pub fn link(input: &[u8], name: &str, target: Target) -> Vec<u8> {

+ 3 - 1
src/sema/ast.rs

@@ -52,7 +52,7 @@ pub enum Type {
 pub struct StructDecl {
     pub tags: Vec<Tag>,
     pub name: String,
-    pub loc: pt::Loc,
+    pub loc: Option<pt::Loc>,
     pub contract: Option<String>,
     pub fields: Vec<Parameter>,
     // List of offsets of the fields, last entry is the offset for the struct overall size
@@ -122,6 +122,7 @@ pub struct Parameter {
     pub ty: Type,
     pub ty_loc: pt::Loc,
     pub indexed: bool,
+    pub readonly: bool,
 }
 
 #[derive(PartialEq, Eq, Clone, Hash, Debug)]
@@ -1329,6 +1330,7 @@ pub enum Builtin {
     WriteUint128LE,
     WriteUint256LE,
     WriteAddress,
+    Accounts,
 }
 
 #[derive(PartialEq, Clone, Debug)]

File diff suppressed because it is too large
+ 727 - 709
src/sema/builtin.rs


+ 1 - 0
src/sema/contracts.rs

@@ -206,6 +206,7 @@ fn resolve_base_args(
             file_no,
             unchecked: false,
             constant: false,
+            lvalue: false,
         };
 
         for base in &def.base {

+ 19 - 17
src/sema/dotgraphviz.rs

@@ -1594,28 +1594,30 @@ impl Namespace {
             let structs = dot.add_node(Node::new("structs", Vec::new()), None, None);
 
             for decl in &self.structs {
-                let mut labels = vec![
-                    format!("name:{}", decl.name),
-                    self.files[decl.loc.0].loc_to_string(&decl.loc),
-                ];
+                if let Some(loc) = &decl.loc {
+                    let mut labels = vec![
+                        format!("name:{}", decl.name),
+                        self.files[loc.0].loc_to_string(loc),
+                    ];
 
-                if let Some(contract) = &decl.contract {
-                    labels.insert(1, format!("contract: {}", contract));
-                }
+                    if let Some(contract) = &decl.contract {
+                        labels.insert(1, format!("contract: {}", contract));
+                    }
 
-                for field in &decl.fields {
-                    labels.push(format!(
-                        "field name:{} ty:{}",
-                        field.name,
-                        field.ty.to_string(self)
-                    ));
-                }
+                    for field in &decl.fields {
+                        labels.push(format!(
+                            "field name:{} ty:{}",
+                            field.name,
+                            field.ty.to_string(self)
+                        ));
+                    }
 
-                let e = Node::new(&decl.name, labels);
+                    let e = Node::new(&decl.name, labels);
 
-                let node = dot.add_node(e, Some(structs), None);
+                    let node = dot.add_node(e, Some(structs), None);
 
-                dot.add_tags(&decl.tags, node);
+                    dot.add_tags(&decl.tags, node);
+                }
             }
         }
 

+ 66 - 25
src/sema/expression.rs

@@ -1402,12 +1402,14 @@ pub struct ExprContext {
     pub file_no: usize,
     // Are we resolving a contract, and if so, which one
     pub contract_no: Option<usize>,
-    // Are resolving the body of a function, and if os, which one
+    /// Are resolving the body of a function, and if os, which one
     pub function_no: Option<usize>,
-    // Are we currently in an unchecked block
+    /// Are we currently in an unchecked block
     pub unchecked: bool,
-    // Are we evaluating a constant expression
+    /// Are we evaluating a constant expression
     pub constant: bool,
+    /// Are we resolving an l-value
+    pub lvalue: bool,
 }
 
 /// Resolve a parsed expression into an AST expression. The resolve_to argument is a hint to what
@@ -3529,7 +3531,7 @@ fn addition(
 }
 
 /// Resolve an assignment
-pub fn assign_single(
+fn assign_single(
     loc: &pt::Loc,
     left: &pt::Expression,
     right: &pt::Expression,
@@ -3538,12 +3540,12 @@ pub fn assign_single(
     symtable: &mut Symtable,
     diagnostics: &mut Vec<Diagnostic>,
 ) -> Result<Expression, ()> {
-    let mut context = context.clone();
-    context.constant = false;
+    let mut lcontext = context.clone();
+    lcontext.lvalue = true;
 
     let var = expression(
         left,
-        &context,
+        &lcontext,
         ns,
         symtable,
         diagnostics,
@@ -3554,7 +3556,7 @@ pub fn assign_single(
     let var_ty = var.ty();
     let val = expression(
         right,
-        &context,
+        context,
         ns,
         symtable,
         diagnostics,
@@ -3666,12 +3668,12 @@ fn assign_expr(
     symtable: &mut Symtable,
     diagnostics: &mut Vec<Diagnostic>,
 ) -> Result<Expression, ()> {
-    let mut context = context.clone();
-    context.constant = false;
+    let mut lcontext = context.clone();
+    lcontext.lvalue = true;
 
     let var = expression(
         left,
-        &context,
+        &lcontext,
         ns,
         symtable,
         diagnostics,
@@ -3689,7 +3691,7 @@ fn assign_expr(
         ResolveTo::Type(var_ty.deref_any())
     };
 
-    let set = expression(right, &context, ns, symtable, diagnostics, resolve_to)?;
+    let set = expression(right, context, ns, symtable, diagnostics, resolve_to)?;
     used_variable(ns, &set, symtable);
     let set_type = set.ty();
 
@@ -3904,7 +3906,7 @@ fn incr_decr(
 
     let mut context = context.clone();
 
-    context.constant = false;
+    context.lvalue = true;
 
     let var = expression(v, &context, ns, symtable, diagnostics, ResolveTo::Unknown)?;
     used_variable(ns, &var, symtable);
@@ -4319,12 +4321,28 @@ fn member_access(
                 .enumerate()
                 .find(|f| id.name == f.1.name)
             {
-                return Ok(Expression::StructMember(
-                    id.loc,
-                    Type::Ref(Box::new(f.ty.clone())),
-                    Box::new(expr),
-                    i,
-                ));
+                return if context.lvalue && f.readonly {
+                    diagnostics.push(Diagnostic::error(
+                        id.loc,
+                        format!("struct ‘{}’ field ‘{}’ is readonly", ns.structs[n], id.name),
+                    ));
+                    Err(())
+                } else if f.readonly {
+                    // readonly fields return the value, not a reference
+                    Ok(Expression::StructMember(
+                        id.loc,
+                        f.ty.clone(),
+                        Box::new(expr),
+                        i,
+                    ))
+                } else {
+                    Ok(Expression::StructMember(
+                        id.loc,
+                        Type::Ref(Box::new(f.ty.clone())),
+                        Box::new(expr),
+                        i,
+                    ))
+                };
             } else {
                 diagnostics.push(Diagnostic::error(
                     id.loc,
@@ -4622,7 +4640,12 @@ fn array_subscript(
                     Box::new(index),
                 ))
             } else {
-                let elem_ty = array_ty.array_deref();
+                let mut elem_ty = array_ty.array_deref();
+
+                if elem_ty.is_builtin(ns) {
+                    // AccountInfo is an array of structures, not an array of pointers to structures
+                    elem_ty = elem_ty.deref_any().clone();
+                }
 
                 let array = cast(
                     &array.loc(),
@@ -4671,7 +4694,18 @@ fn struct_literal(
 ) -> Result<Expression, ()> {
     let struct_def = ns.structs[struct_no].clone();
 
-    if args.len() != struct_def.fields.len() {
+    let ty = Type::Struct(struct_no);
+
+    if ty.contains_builtins(ns).is_some() {
+        diagnostics.push(Diagnostic::error(
+            *loc,
+            format!(
+                "builtin struct ‘{}’ cannot be created using struct literal",
+                struct_def.name,
+            ),
+        ));
+        Err(())
+    } else if args.len() != struct_def.fields.len() {
         diagnostics.push(Diagnostic::error(
             *loc,
             format!(
@@ -4705,8 +4739,6 @@ fn struct_literal(
             )?);
         }
 
-        let ty = Type::Struct(struct_no);
-
         Ok(Expression::StructLiteral(*loc, ty, fields))
     }
 }
@@ -5242,8 +5274,18 @@ fn named_struct_literal(
     diagnostics: &mut Vec<Diagnostic>,
 ) -> Result<Expression, ()> {
     let struct_def = ns.structs[struct_no].clone();
+    let ty = Type::Struct(struct_no);
 
-    if args.len() != struct_def.fields.len() {
+    if ty.contains_builtins(ns).is_some() {
+        diagnostics.push(Diagnostic::error(
+            *loc,
+            format!(
+                "builtin struct ‘{}’ cannot be created using struct literal",
+                struct_def.name,
+            ),
+        ));
+        Err(())
+    } else if args.len() != struct_def.fields.len() {
         diagnostics.push(Diagnostic::error(
             *loc,
             format!(
@@ -5288,7 +5330,6 @@ fn named_struct_literal(
                 }
             }
         }
-        let ty = Type::Struct(struct_no);
         Ok(Expression::StructLiteral(*loc, ty, fields))
     }
 }

+ 33 - 8
src/sema/functions.rs

@@ -799,12 +799,23 @@ pub fn resolve_params(
 
         match ns.resolve_type(file_no, contract_no, false, &p.ty, diagnostics) {
             Ok(ty) => {
-                if !is_internal && ty.contains_internal_function(ns) {
-                    diagnostics.push(Diagnostic::error(
+                if !is_internal {
+                    if ty.contains_internal_function(ns) {
+                        diagnostics.push(Diagnostic::error(
                         p.ty.loc(),
                         "parameter of type ‘function internal’ not allowed public or external functions".to_string(),
                     ));
-                    success = false;
+                        success = false;
+                    }
+
+                    if let Some(ty) = ty.contains_builtins(ns) {
+                        let message = format!(
+                            "parameter of type ‘{}’ not alowed in public or external functions",
+                            ty.to_string(ns)
+                        );
+                        ns.diagnostics.push(Diagnostic::error(p.ty.loc(), message));
+                        success = false
+                    }
                 }
 
                 let ty = if !ty.can_have_data_location() {
@@ -861,6 +872,7 @@ pub fn resolve_params(
                     ty,
                     ty_loc,
                     indexed: false,
+                    readonly: false,
                 });
             }
             Err(()) => success = false,
@@ -896,15 +908,25 @@ pub fn resolve_returns(
 
         match ns.resolve_type(file_no, contract_no, false, &r.ty, diagnostics) {
             Ok(ty) => {
-                if !is_internal && ty.contains_internal_function(ns) {
-                    diagnostics.push(Diagnostic::error(
+                if !is_internal {
+                    if ty.contains_internal_function(ns) {
+                        diagnostics.push(Diagnostic::error(
                         r.ty.loc(),
-                        "return type ‘function internal’ not allowed public or external functions"
+                        "return type ‘function internal’ not allowed in public or external functions"
                             .to_string(),
                     ));
-                    success = false;
-                }
+                        success = false;
+                    }
 
+                    if let Some(ty) = ty.contains_builtins(ns) {
+                        let message = format!(
+                            "return type ‘{}’ not allowed in public or external functions",
+                            ty.to_string(ns)
+                        );
+                        ns.diagnostics.push(Diagnostic::error(r.ty.loc(), message));
+                        success = false
+                    }
+                }
                 let ty = if !ty.can_have_data_location() {
                     if let Some(storage) = &r.storage {
                         diagnostics.push(Diagnostic::error(
@@ -965,6 +987,7 @@ pub fn resolve_returns(
                     ty,
                     ty_loc,
                     indexed: false,
+                    readonly: false,
                 });
             }
             Err(()) => success = false,
@@ -1003,6 +1026,7 @@ fn signatures() {
                 ty: Type::Uint(8),
                 ty_loc: pt::Loc(0, 0, 0),
                 indexed: false,
+                readonly: false,
             },
             Parameter {
                 loc: pt::Loc(0, 0, 0),
@@ -1011,6 +1035,7 @@ fn signatures() {
                 ty: Type::Address(false),
                 ty_loc: pt::Loc(0, 0, 0),
                 indexed: false,
+                readonly: false,
             },
         ],
         Vec::new(),

+ 8 - 1
src/sema/mod.rs

@@ -323,7 +323,7 @@ impl ast::Namespace {
             Target::Solana => (32, 8),
         };
 
-        ast::Namespace {
+        let mut ns = ast::Namespace {
             target,
             files: Vec::new(),
             enums: Vec::new(),
@@ -340,7 +340,13 @@ impl ast::Namespace {
             next_id: 0,
             var_constants: HashMap::new(),
             hover_overrides: HashMap::new(),
+        };
+
+        if target == Target::Solana {
+            ns.add_solana_builtins();
         }
+
+        ns
     }
 
     /// Add symbol to symbol table; either returns true for success, or adds an appropriate error
@@ -1486,6 +1492,7 @@ impl ast::Namespace {
             contract_no,
             function_no,
             constant: true,
+            lvalue: false,
         };
 
         let size_expr = expression(

+ 11 - 1
src/sema/statements.rs

@@ -27,6 +27,7 @@ pub fn resolve_function_body(
         function_no: Some(function_no),
         unchecked: false,
         constant: false,
+        lvalue: false,
     };
 
     // first add function parameters
@@ -344,6 +345,7 @@ fn statement(
                         name: decl.name.name.to_owned(),
                         name_loc: Some(decl.name.loc),
                         indexed: false,
+                        readonly: false,
                     },
                     initializer,
                 ));
@@ -1085,6 +1087,9 @@ fn destructure(
     let mut fields = Vec::new();
     let mut left_tys = Vec::new();
 
+    let mut lcontext = context.clone();
+    lcontext.lvalue = true;
+
     for (_, param) in vars {
         match param {
             None => {
@@ -1106,7 +1111,7 @@ fn destructure(
                 }
 
                 // ty will just be a normal expression, not a type
-                let e = expression(ty, context, ns, symtable, diagnostics, ResolveTo::Unknown)?;
+                let e = expression(ty, &lcontext, ns, symtable, diagnostics, ResolveTo::Unknown)?;
 
                 match &e {
                     Expression::ConstantVariable(_, _, Some(contract_no), var_no) => {
@@ -1188,6 +1193,7 @@ fn destructure(
                             ty,
                             ty_loc,
                             indexed: false,
+                            readonly: false,
                         },
                     ));
                 }
@@ -1878,6 +1884,7 @@ fn try_catch(
                                 name: name.name.to_string(),
                                 name_loc: Some(name.loc),
                                 indexed: false,
+                                readonly: false,
                             },
                         ));
                     }
@@ -1891,6 +1898,7 @@ fn try_catch(
                             indexed: false,
                             name: "".to_string(),
                             name_loc: None,
+                            readonly: false,
                         },
                     ));
                 }
@@ -1964,6 +1972,7 @@ fn try_catch(
             name: "".to_string(),
             name_loc: None,
             indexed: false,
+            readonly: false,
         };
 
         if let Some(name) = &error_stmt.1.name {
@@ -2029,6 +2038,7 @@ fn try_catch(
             name: "".to_owned(),
             name_loc: None,
             indexed: false,
+            readonly: false,
         };
 
         if let Some(name) = &param.name {

+ 32 - 4
src/sema/types.rs

@@ -51,7 +51,7 @@ pub fn resolve_typenames<'a>(
                     ns.structs.push(StructDecl {
                         tags: Vec::new(),
                         name: def.name.name.to_owned(),
-                        loc: def.name.loc,
+                        loc: Some(def.name.loc),
                         contract: None,
                         fields: Vec::new(),
                         offsets: Vec::new(),
@@ -124,7 +124,7 @@ pub fn resolve_fields(delay: ResolveFields, file_no: usize, ns: &mut Namespace)
 
                     if structs_visited.contains(&struct_no) {
                         ns.diagnostics.push(Diagnostic::error_with_note(
-                            def.loc,
+                            def.loc.unwrap(),
                             format!("struct ‘{}’ has infinite size", def.name),
                             field.loc,
                             format!("recursive field ‘{}’", field.name),
@@ -196,7 +196,7 @@ fn resolve_contract<'a>(
                     ns.structs.push(StructDecl {
                         tags: Vec::new(),
                         name: s.name.name.to_owned(),
-                        loc: s.name.loc,
+                        loc: Some(s.name.loc),
                         contract: Some(def.name.name.to_owned()),
                         fields: Vec::new(),
                         offsets: Vec::new(),
@@ -308,6 +308,7 @@ pub fn struct_decl(
             ty,
             ty_loc: field.ty.loc(),
             indexed: false,
+            readonly: false,
         });
     }
 
@@ -403,6 +404,7 @@ fn event_decl(
             ty,
             ty_loc: field.ty.loc(),
             indexed: field.indexed,
+            readonly: false,
         });
     }
 
@@ -833,7 +835,7 @@ impl Type {
             }
             Type::Mapping(_, _) => BigInt::zero(),
             Type::Ref(ty) | Type::StorageRef(_, ty) => ty.size_of(ns),
-            _ => unimplemented!(),
+            _ => unimplemented!("sizeof on {:?}", self),
         }
     }
 
@@ -1142,6 +1144,32 @@ impl Type {
         }
     }
 
+    /// Is this structure a builtin
+    pub fn is_builtin(&self, ns: &Namespace) -> bool {
+        match self {
+            Type::Struct(n) => ns.structs[*n].loc.is_none(),
+            Type::StorageRef(_, r) | Type::Ref(r) => r.is_builtin(ns),
+            _ => false,
+        }
+    }
+
+    /// Does the type contain any builtin type
+    pub fn contains_builtins<'a>(&'a self, ns: &'a Namespace) -> Option<&'a Type> {
+        match self {
+            Type::Array(ty, _) => ty.contains_builtins(ns),
+            Type::Mapping(key, value) => key
+                .contains_builtins(ns)
+                .or_else(|| value.contains_builtins(ns)),
+            Type::Struct(n) if ns.structs[*n].loc.is_none() => Some(self),
+            Type::Struct(n) => ns.structs[*n]
+                .fields
+                .iter()
+                .find_map(|f| f.ty.contains_builtins(ns)),
+            Type::StorageRef(_, r) | Type::Ref(r) => r.contains_builtins(ns),
+            _ => None,
+        }
+    }
+
     /// If the type is Ref or StorageRef, get the underlying type
     pub fn deref_any(&self) -> &Self {
         match self {

+ 11 - 0
src/sema/variables.rs

@@ -218,6 +218,13 @@ pub fn var_decl(
             ),
         ));
         return None;
+    } else if let Some(ty) = ty.contains_builtins(ns) {
+        let message = format!(
+            "variable of cannot be builtin of type ‘{}’",
+            ty.to_string(ns)
+        );
+        ns.diagnostics.push(Diagnostic::error(s.ty.loc(), message));
+        return None;
     }
 
     let initializer = if let Some(initializer) = &s.initializer {
@@ -228,6 +235,7 @@ pub fn var_decl(
             contract_no,
             function_no: None,
             constant,
+            lvalue: false,
         };
 
         match expression(
@@ -367,6 +375,7 @@ pub fn var_decl(
                     ty: ty.clone(),
                     ty_loc: s.ty.loc(),
                     indexed: false,
+                    readonly: false,
                 }],
                 ns,
             );
@@ -433,6 +442,7 @@ fn collect_parameters<'a>(
                 ty: key.as_ref().clone(),
                 ty_loc: pt::Loc(0, 0, 0),
                 indexed: false,
+                readonly: false,
             });
 
             collect_parameters(value, params, expr, ns)
@@ -463,6 +473,7 @@ fn collect_parameters<'a>(
                     ty: Type::Uint(256),
                     ty_loc: pt::Loc(0, 0, 0),
                     indexed: false,
+                    readonly: false,
                 });
             }
 

+ 2 - 2
tests/contract_testcases/solana/accessor/constant.dot

@@ -6,7 +6,7 @@ strict digraph "tests/contract_testcases/solana/accessor/constant.sol" {
 	return [label="return\ntests/contract_testcases/solana/accessor/constant.sol:1:1"]
 	constant [label="constant variable\nx.z\nbytes32\ntests/contract_testcases/solana/accessor/constant.sol:1:1"]
 	diagnostic [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/accessor/constant.sol:2:9-20"]
-	diagnostic_9 [label="cannot call function in constant expression\nlevel Error\ntests/contract_testcases/solana/accessor/constant.sol:3:41-53"]
+	diagnostic_10 [label="cannot call function in constant expression\nlevel Error\ntests/contract_testcases/solana/accessor/constant.sol:3:41-53"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> z [label="function"]
@@ -14,5 +14,5 @@ strict digraph "tests/contract_testcases/solana/accessor/constant.sol" {
 	z -> return [label="body"]
 	return -> constant [label="expr"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_9 [label="Error"]
+	diagnostics -> diagnostic_10 [label="Error"]
 }

+ 6 - 6
tests/contract_testcases/solana/accessor/constant_01.dot

@@ -1,22 +1,22 @@
 strict digraph "tests/contract_testcases/solana/accessor/constant_01.sol" {
 	contract [label="contract x\ntests/contract_testcases/solana/accessor/constant_01.sol:2:9-20"]
 	var [label="variable foo\nvisibility internal\ntests/contract_testcases/solana/accessor/constant_01.sol:3:13-22"]
-	var_3 [label="variable z\nvisibility public\nconstant\ntests/contract_testcases/solana/accessor/constant_01.sol:4:13-55"]
+	var_4 [label="variable z\nvisibility public\nconstant\ntests/contract_testcases/solana/accessor/constant_01.sol:4:13-55"]
 	z [label="function z\ncontract: x\ntests/contract_testcases/solana/accessor/constant_01.sol:4:37-38\nsignature z()\nvisibility public\nmutability view"]
 	returns [label="returns\nbytes32 "]
 	return [label="return\ntests/contract_testcases/solana/accessor/constant_01.sol:1:1"]
 	constant [label="constant variable\nx.z\nbytes32\ntests/contract_testcases/solana/accessor/constant_01.sol:1:1"]
 	diagnostic [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/accessor/constant_01.sol:2:9-20"]
-	diagnostic_10 [label="cannot read contract variable ‘foo’ in constant expression\nlevel Error\ntests/contract_testcases/solana/accessor/constant_01.sol:4:51-54"]
-	diagnostic_11 [label="storage variable 'foo' has never been used\nlevel Warning\ntests/contract_testcases/solana/accessor/constant_01.sol:3:13-22"]
+	diagnostic_11 [label="cannot read contract variable ‘foo’ in constant expression\nlevel Error\ntests/contract_testcases/solana/accessor/constant_01.sol:4:51-54"]
+	diagnostic_12 [label="storage variable 'foo' has never been used\nlevel Warning\ntests/contract_testcases/solana/accessor/constant_01.sol:3:13-22"]
 	contracts -> contract
 	contract -> var [label="variable"]
-	contract -> var_3 [label="variable"]
+	contract -> var_4 [label="variable"]
 	contract -> z [label="function"]
 	z -> returns [label="returns"]
 	z -> return [label="body"]
 	return -> constant [label="expr"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_10 [label="Error"]
-	diagnostics -> diagnostic_11 [label="Warning"]
+	diagnostics -> diagnostic_11 [label="Error"]
+	diagnostics -> diagnostic_12 [label="Warning"]
 }

+ 28 - 0
tests/contract_testcases/solana/account_info.dot

@@ -0,0 +1,28 @@
+strict digraph "tests/contract_testcases/solana/account_info.sol" {
+	contract [label="contract c\ntests/contract_testcases/solana/account_info.sol:1:1-12"]
+	f [label="function f\ncontract: c\ntests/contract_testcases/solana/account_info.sol:6:2-21\nsignature f()\nvisibility public\nmutability nonpayable"]
+	f2 [label="function f2\ncontract: c\ntests/contract_testcases/solana/account_info.sol:11:2-22\nsignature f2()\nvisibility public\nmutability nonpayable"]
+	notpub [label="function notpub\ncontract: c\ntests/contract_testcases/solana/account_info.sol:16:2-60\nsignature notpub((bytes32,uint64,bytes,bytes32,uint64,bool,bool,bool))\nvisibility private\nmutability nonpayable"]
+	parameters [label="parameters\nstruct AccountInfo "]
+	returns [label="returns\nstruct AccountInfo "]
+	diagnostic [label="found contract ‘c’\nlevel Debug\ntests/contract_testcases/solana/account_info.sol:1:1-12"]
+	diagnostic_10 [label="variable of cannot be builtin of type ‘struct AccountInfo’\nlevel Error\ntests/contract_testcases/solana/account_info.sol:2:2-13"]
+	diagnostic_11 [label="parameter of type ‘struct AccountInfo’ not alowed in public or external functions\nlevel Error\ntests/contract_testcases/solana/account_info.sol:4:15-26"]
+	diagnostic_12 [label="return type ‘struct AccountInfo’ not allowed in public or external functions\nlevel Error\ntests/contract_testcases/solana/account_info.sol:4:44-55"]
+	diagnostic_13 [label="builtin struct ‘AccountInfo’ cannot be created using struct literal\nlevel Error\ntests/contract_testcases/solana/account_info.sol:8:8-36"]
+	diagnostic_14 [label="builtin struct ‘AccountInfo’ cannot be created using struct literal\nlevel Error\ntests/contract_testcases/solana/account_info.sol:13:8-22"]
+	diagnostic_15 [label="struct ‘AccountInfo’ field ‘key’ is readonly\nlevel Error\ntests/contract_testcases/solana/account_info.sol:18:6-9"]
+	contracts -> contract
+	contract -> f [label="function"]
+	contract -> f2 [label="function"]
+	contract -> notpub [label="function"]
+	notpub -> parameters [label="parameters"]
+	notpub -> returns [label="returns"]
+	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_10 [label="Error"]
+	diagnostics -> diagnostic_11 [label="Error"]
+	diagnostics -> diagnostic_12 [label="Error"]
+	diagnostics -> diagnostic_13 [label="Error"]
+	diagnostics -> diagnostic_14 [label="Error"]
+	diagnostics -> diagnostic_15 [label="Error"]
+}

+ 22 - 0
tests/contract_testcases/solana/account_info.sol

@@ -0,0 +1,22 @@
+contract c {
+	AccountInfo ai;
+
+	function pub(AccountInfo) public returns (AccountInfo) {}
+
+	function f() public {
+		AccountInfo ai;
+		ai = AccountInfo({lamports: "x"});
+	}
+
+	function f2() public {
+		AccountInfo ai;
+		ai = AccountInfo(1);
+	}
+
+	function notpub(AccountInfo) private returns (AccountInfo) {
+		AccountInfo ai = tx.accounts[1];
+		ai.key = msg.sender;
+		ai.lamports += 1;
+		return tx.accounts[1];
+	}
+}

+ 2 - 2
tests/contract_testcases/solana/assembly/parse.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/assembly/parse.sol" {
 	get [label="function get\ncontract: foo\ntests/contract_testcases/solana/assembly/parse.sol:3:13-51\nsignature get()\nvisibility public\nmutability nonpayable"]
 	returns [label="returns\nbytes4 "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/assembly/parse.sol:2:9-22"]
-	diagnostic_6 [label="evm assembly not supported on target solana\nlevel Error\ntests/contract_testcases/solana/assembly/parse.sol:4:17-7:18"]
+	diagnostic_7 [label="evm assembly not supported on target solana\nlevel Error\ntests/contract_testcases/solana/assembly/parse.sol:4:17-7:18"]
 	contracts -> contract
 	contract -> get [label="function"]
 	get -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/call/calltys.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/solana/call/calltys.sol" {
 	contract [label="contract main\ntests/contract_testcases/solana/call/calltys.sol:2:9-23"]
 	test [label="function test\ncontract: main\ntests/contract_testcases/solana/call/calltys.sol:3:13-35\nsignature test()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘main’\nlevel Debug\ntests/contract_testcases/solana/call/calltys.sol:2:9-23"]
-	diagnostic_5 [label="method ‘staticcall’ does not exist\nlevel Error\ntests/contract_testcases/solana/call/calltys.sol:6:19-29"]
+	diagnostic_6 [label="method ‘staticcall’ does not exist\nlevel Error\ntests/contract_testcases/solana/call/calltys.sol:6:19-29"]
 	contracts -> contract
 	contract -> test [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/call/calltys_01.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/solana/call/calltys_01.sol" {
 	contract [label="contract main\ntests/contract_testcases/solana/call/calltys_01.sol:2:9-23"]
 	test [label="function test\ncontract: main\ntests/contract_testcases/solana/call/calltys_01.sol:3:13-35\nsignature test()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘main’\nlevel Debug\ntests/contract_testcases/solana/call/calltys_01.sol:2:9-23"]
-	diagnostic_5 [label="method ‘delegatecall’ does not exist\nlevel Error\ntests/contract_testcases/solana/call/calltys_01.sol:6:19-31"]
+	diagnostic_6 [label="method ‘delegatecall’ does not exist\nlevel Error\ntests/contract_testcases/solana/call/calltys_01.sol:6:19-31"]
 	contracts -> contract
 	contract -> test [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/call/calltys_02.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/solana/call/calltys_02.sol" {
 	contract [label="contract main\ntests/contract_testcases/solana/call/calltys_02.sol:2:9-23"]
 	test [label="function test\ncontract: main\ntests/contract_testcases/solana/call/calltys_02.sol:3:13-35\nsignature test()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘main’\nlevel Debug\ntests/contract_testcases/solana/call/calltys_02.sol:2:9-23"]
-	diagnostic_5 [label="‘gas’ not permitted for external calls or constructors on solana\nlevel Error\ntests/contract_testcases/solana/call/calltys_02.sol:6:51-57"]
+	diagnostic_6 [label="‘gas’ not permitted for external calls or constructors on solana\nlevel Error\ntests/contract_testcases/solana/call/calltys_02.sol:6:51-57"]
 	contracts -> contract
 	contract -> test [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }

+ 9 - 9
tests/contract_testcases/solana/constant/not_constant.dot

@@ -6,12 +6,12 @@ strict digraph "tests/contract_testcases/solana/constant/not_constant.sol" {
 	returns [label="returns\nuint256 "]
 	return [label="return\ntests/contract_testcases/solana/constant/not_constant.sol:1:1"]
 	constant [label="constant variable\nC.STATIC\nuint256\ntests/contract_testcases/solana/constant/not_constant.sol:1:1"]
-	contract_8 [label="contract foo\ntests/contract_testcases/solana/constant/not_constant.sol:6:9-22"]
+	contract_9 [label="contract foo\ntests/contract_testcases/solana/constant/not_constant.sol:6:9-22"]
 	f [label="function f\ncontract: foo\ntests/contract_testcases/solana/constant/not_constant.sol:7:13-47\nsignature f()\nvisibility public\nmutability nonpayable"]
-	returns_10 [label="returns\nuint256 "]
+	returns_11 [label="returns\nuint256 "]
 	diagnostic [label="found contract ‘C’\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant.sol:2:9-20"]
-	diagnostic_13 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant.sol:6:9-22"]
-	diagnostic_14 [label="`C' is a contract\nlevel Error\ntests/contract_testcases/solana/constant/not_constant.sol:8:26-27"]
+	diagnostic_14 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant.sol:6:9-22"]
+	diagnostic_15 [label="`C' is a contract\nlevel Error\ntests/contract_testcases/solana/constant/not_constant.sol:8:26-27"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
@@ -19,10 +19,10 @@ strict digraph "tests/contract_testcases/solana/constant/not_constant.sol" {
 	STATIC -> returns [label="returns"]
 	STATIC -> return [label="body"]
 	return -> constant [label="expr"]
-	contracts -> contract_8
-	contract_8 -> f [label="function"]
-	f -> returns_10 [label="returns"]
+	contracts -> contract_9
+	contract_9 -> f [label="function"]
+	f -> returns_11 [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_13 [label="Debug"]
-	diagnostics -> diagnostic_14 [label="Error"]
+	diagnostics -> diagnostic_14 [label="Debug"]
+	diagnostics -> diagnostic_15 [label="Error"]
 }

+ 9 - 9
tests/contract_testcases/solana/constant/not_constant_01.dot

@@ -7,12 +7,12 @@ strict digraph "tests/contract_testcases/solana/constant/not_constant_01.sol" {
 	return [label="return\ntests/contract_testcases/solana/constant/not_constant_01.sol:1:1"]
 	storage_load [label="storage load uint256\ntests/contract_testcases/solana/constant/not_constant_01.sol:1:1"]
 	storage_var [label="storage variable\nC.NOT_CONSTANT\nuint256 storage\ntests/contract_testcases/solana/constant/not_constant_01.sol:1:1"]
-	contract_9 [label="contract foo\ntests/contract_testcases/solana/constant/not_constant_01.sol:6:9-22"]
+	contract_10 [label="contract foo\ntests/contract_testcases/solana/constant/not_constant_01.sol:6:9-22"]
 	f [label="function f\ncontract: foo\ntests/contract_testcases/solana/constant/not_constant_01.sol:7:13-47\nsignature f()\nvisibility public\nmutability nonpayable"]
-	returns_11 [label="returns\nuint256 "]
+	returns_12 [label="returns\nuint256 "]
 	diagnostic [label="found contract ‘C’\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant_01.sol:2:9-20"]
-	diagnostic_14 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant_01.sol:6:9-22"]
-	diagnostic_15 [label="need instance of contract ‘C’ to get variable value ‘NOT_CONSTANT’\nlevel Error\ntests/contract_testcases/solana/constant/not_constant_01.sol:8:26-40"]
+	diagnostic_15 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/constant/not_constant_01.sol:6:9-22"]
+	diagnostic_16 [label="need instance of contract ‘C’ to get variable value ‘NOT_CONSTANT’\nlevel Error\ntests/contract_testcases/solana/constant/not_constant_01.sol:8:26-40"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
@@ -21,10 +21,10 @@ strict digraph "tests/contract_testcases/solana/constant/not_constant_01.sol" {
 	NOT_CONSTANT -> return [label="body"]
 	return -> storage_load [label="expr"]
 	storage_load -> storage_var [label="expr"]
-	contracts -> contract_9
-	contract_9 -> f [label="function"]
-	f -> returns_11 [label="returns"]
+	contracts -> contract_10
+	contract_10 -> f [label="function"]
+	f -> returns_12 [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_14 [label="Debug"]
-	diagnostics -> diagnostic_15 [label="Error"]
+	diagnostics -> diagnostic_15 [label="Debug"]
+	diagnostics -> diagnostic_16 [label="Error"]
 }

+ 6 - 6
tests/contract_testcases/solana/create_contract/syntax.dot

@@ -1,14 +1,14 @@
 strict digraph "tests/contract_testcases/solana/create_contract/syntax.sol" {
 	contract [label="contract y\ntests/contract_testcases/solana/create_contract/syntax.sol:2:9-20"]
 	f [label="function f\ncontract: y\ntests/contract_testcases/solana/create_contract/syntax.sol:3:13-32\nsignature f()\nvisibility public\nmutability nonpayable"]
-	contract_3 [label="contract x\ntests/contract_testcases/solana/create_contract/syntax.sol:7:9-20"]
+	contract_4 [label="contract x\ntests/contract_testcases/solana/create_contract/syntax.sol:7:9-20"]
 	diagnostic [label="found contract ‘y’\nlevel Debug\ntests/contract_testcases/solana/create_contract/syntax.sol:2:9-20"]
-	diagnostic_6 [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/create_contract/syntax.sol:7:9-20"]
-	diagnostic_7 [label="‘gas’ not permitted for external calls or constructors on solana\nlevel Error\ntests/contract_testcases/solana/create_contract/syntax.sol:4:29-37"]
+	diagnostic_7 [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/create_contract/syntax.sol:7:9-20"]
+	diagnostic_8 [label="‘gas’ not permitted for external calls or constructors on solana\nlevel Error\ntests/contract_testcases/solana/create_contract/syntax.sol:4:29-37"]
 	contracts -> contract
 	contract -> f [label="function"]
-	contracts -> contract_3
+	contracts -> contract_4
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Debug"]
+	diagnostics -> diagnostic_8 [label="Error"]
 }

+ 6 - 6
tests/contract_testcases/solana/create_contract/syntax_01.dot

@@ -1,14 +1,14 @@
 strict digraph "tests/contract_testcases/solana/create_contract/syntax_01.sol" {
 	contract [label="contract y\ntests/contract_testcases/solana/create_contract/syntax_01.sol:2:9-20"]
 	f [label="function f\ncontract: y\ntests/contract_testcases/solana/create_contract/syntax_01.sol:3:13-32\nsignature f()\nvisibility public\nmutability nonpayable"]
-	contract_3 [label="contract x\ntests/contract_testcases/solana/create_contract/syntax_01.sol:7:9-20"]
+	contract_4 [label="contract x\ntests/contract_testcases/solana/create_contract/syntax_01.sol:7:9-20"]
 	diagnostic [label="found contract ‘y’\nlevel Debug\ntests/contract_testcases/solana/create_contract/syntax_01.sol:2:9-20"]
-	diagnostic_6 [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/create_contract/syntax_01.sol:7:9-20"]
-	diagnostic_7 [label="‘salt’ not permitted for external calls or constructors on solana\nlevel Error\ntests/contract_testcases/solana/create_contract/syntax_01.sol:4:29-38"]
+	diagnostic_7 [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/create_contract/syntax_01.sol:7:9-20"]
+	diagnostic_8 [label="‘salt’ not permitted for external calls or constructors on solana\nlevel Error\ntests/contract_testcases/solana/create_contract/syntax_01.sol:4:29-38"]
 	contracts -> contract
 	contract -> f [label="function"]
-	contracts -> contract_3
+	contracts -> contract_4
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Debug"]
+	diagnostics -> diagnostic_8 [label="Error"]
 }

+ 200 - 200
tests/contract_testcases/solana/doccomments_everywhere.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/doccomments_everywhere.sol" {
 	contract [label="contract Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:4:107-5:19"]
 	tags [label="author: Max Campbell (https://github.com/maxall41), RafaCypherpunk (https://github.com/RafaCypherpunk)"]
 	var [label="variable pricePerShare_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:9:3-52"]
-	var_6 [label="variable valueLocked_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:10:3-50"]
-	var_7 [label="variable tokenDeployers_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:11:3-53"]
-	var_8 [label="variable sellingTokens_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:12:3-52"]
-	var_9 [label="variable buyingTokens_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:13:3-51"]
+	var_7 [label="variable valueLocked_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:10:3-50"]
+	var_8 [label="variable tokenDeployers_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:11:3-53"]
+	var_9 [label="variable sellingTokens_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:12:3-52"]
+	var_10 [label="variable buyingTokens_\nvisibility public\ntests/contract_testcases/solana/doccomments_everywhere.sol:13:3-51"]
 	pricePerShare_ [label="function pricePerShare_\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:9:38-52\nsignature pricePerShare_(uint256)\nvisibility public\nmutability view"]
 	parameters [label="parameters\nuint256 "]
 	returns [label="returns\nuint256 "]
@@ -16,132 +16,132 @@ strict digraph "tests/contract_testcases/solana/doccomments_everywhere.sol" {
 	storage_var [label="storage variable\nProperty.pricePerShare_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
 	func_arg [label="func arg #0: uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
 	valueLocked_ [label="function valueLocked_\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:10:38-50\nsignature valueLocked_(bytes32)\nvisibility public\nmutability view"]
-	parameters_19 [label="parameters\naddress "]
-	returns_20 [label="returns\nuint256 "]
-	return_21 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_load_22 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	subscript_23 [label="subscript mapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_var_24 [label="storage variable\nProperty.valueLocked_\nmapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	func_arg_25 [label="func arg #0: address\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	parameters_20 [label="parameters\naddress "]
+	returns_21 [label="returns\nuint256 "]
+	return_22 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_load_23 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	subscript_24 [label="subscript mapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_var_25 [label="storage variable\nProperty.valueLocked_\nmapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	func_arg_26 [label="func arg #0: address\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
 	tokenDeployers_ [label="function tokenDeployers_\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:11:38-53\nsignature tokenDeployers_(uint256)\nvisibility public\nmutability view"]
-	parameters_27 [label="parameters\nuint256 "]
-	returns_28 [label="returns\naddress "]
-	return_29 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_load_30 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	subscript_31 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_var_32 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	func_arg_33 [label="func arg #0: uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	parameters_28 [label="parameters\nuint256 "]
+	returns_29 [label="returns\naddress "]
+	return_30 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_load_31 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	subscript_32 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_var_33 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	func_arg_34 [label="func arg #0: uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
 	sellingTokens_ [label="function sellingTokens_\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:12:38-52\nsignature sellingTokens_(uint256)\nvisibility public\nmutability view"]
-	parameters_35 [label="parameters\nuint256 "]
-	returns_36 [label="returns\nuint256 "]
-	return_37 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_load_38 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	subscript_39 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_var_40 [label="storage variable\nProperty.sellingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	func_arg_41 [label="func arg #0: uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	parameters_36 [label="parameters\nuint256 "]
+	returns_37 [label="returns\nuint256 "]
+	return_38 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_load_39 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	subscript_40 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_var_41 [label="storage variable\nProperty.sellingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	func_arg_42 [label="func arg #0: uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
 	buyingTokens_ [label="function buyingTokens_\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:13:38-51\nsignature buyingTokens_(uint256)\nvisibility public\nmutability view"]
-	parameters_43 [label="parameters\nuint256 "]
-	returns_44 [label="returns\nuint256 "]
-	return_45 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_load_46 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	subscript_47 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	storage_var_48 [label="storage variable\nProperty.buyingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	func_arg_49 [label="func arg #0: uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
-	node_50 [label="constructor \ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:17:3-76\nsignature ()\nvisibility public\nmutability nonpayable"]
-	node_51 [label="receive \ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:19:3-29\nmutability payable"]
+	parameters_44 [label="parameters\nuint256 "]
+	returns_45 [label="returns\nuint256 "]
+	return_46 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_load_47 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	subscript_48 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	storage_var_49 [label="storage variable\nProperty.buyingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	func_arg_50 [label="func arg #0: uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:1"]
+	node_51 [label="constructor \ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:17:3-76\nsignature ()\nvisibility public\nmutability nonpayable"]
+	node_52 [label="receive \ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:19:3-29\nmutability payable"]
 	expr [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:5-68"]
 	assign [label="assign\nuint256 storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:30-31"]
-	subscript_54 [label="subscript mapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:5-29"]
-	storage_var_55 [label="storage variable\nProperty.valueLocked_\nmapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:5-17"]
+	subscript_55 [label="subscript mapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:5-29"]
+	storage_var_56 [label="storage variable\nProperty.valueLocked_\nmapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:5-17"]
 	cast [label="cast address\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:18-28"]
 	builtins [label="builtin Sender\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:18-28"]
 	add [label="add\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:57-58"]
-	storage_load_59 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:32-56"]
-	subscript_60 [label="subscript mapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:32-56"]
-	storage_var_61 [label="storage variable\nProperty.valueLocked_\nmapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:32-44"]
-	cast_62 [label="cast address\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:45-55"]
-	builtins_63 [label="builtin Sender\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:45-55"]
+	storage_load_60 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:32-56"]
+	subscript_61 [label="subscript mapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:32-56"]
+	storage_var_62 [label="storage variable\nProperty.valueLocked_\nmapping(address => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:32-44"]
+	cast_63 [label="cast address\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:45-55"]
+	builtins_64 [label="builtin Sender\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:45-55"]
 	sign_ext [label="sign extend uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:59-68"]
-	builtins_65 [label="builtin Value\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:59-68"]
+	builtins_66 [label="builtin Value\ntests/contract_testcases/solana/doccomments_everywhere.sol:20:59-68"]
 	mintProperty [label="function mintProperty\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:23:3-27:11\nsignature mintProperty(uint256,uint256,uint256)\nvisibility public\nmutability nonpayable"]
-	parameters_67 [label="parameters\nuint256 _shares\nuint256 _pricePerShare\nuint256 _sharesForSale"]
+	parameters_68 [label="parameters\nuint256 _shares\nuint256 _pricePerShare\nuint256 _sharesForSale"]
 	getTokenOwner [label="function getTokenOwner\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:37:3-76\nsignature getTokenOwner(uint256)\nvisibility public\nmutability view"]
-	parameters_69 [label="parameters\nuint256 _id"]
-	returns_70 [label="returns\naddress payable "]
-	return_71 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:5-41"]
-	cast_72 [label="cast address payable\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:12-41"]
-	storage_load_73 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:12-41"]
-	subscript_74 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:20-40"]
-	storage_var_75 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:20-35"]
+	parameters_70 [label="parameters\nuint256 _id"]
+	returns_71 [label="returns\naddress payable "]
+	return_72 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:5-41"]
+	cast_73 [label="cast address payable\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:12-41"]
+	storage_load_74 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:12-41"]
+	subscript_75 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:20-40"]
+	storage_var_76 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:20-35"]
 	variable [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:38:36-39"]
 	getPricePerShare [label="function getPricePerShare\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:41:3-71\nsignature getPricePerShare(uint256)\nvisibility public\nmutability view"]
-	parameters_78 [label="parameters\nuint256 _id"]
-	returns_79 [label="returns\nuint256 "]
-	return_80 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:5-31"]
-	storage_load_81 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:5-31"]
-	subscript_82 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:12-31"]
-	storage_var_83 [label="storage variable\nProperty.pricePerShare_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:12-26"]
-	variable_84 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:27-30"]
+	parameters_79 [label="parameters\nuint256 _id"]
+	returns_80 [label="returns\nuint256 "]
+	return_81 [label="return\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:5-31"]
+	storage_load_82 [label="storage load uint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:5-31"]
+	subscript_83 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:12-31"]
+	storage_var_84 [label="storage variable\nProperty.pricePerShare_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:12-26"]
+	variable_85 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:42:27-30"]
 	purchaseShares [label="function purchaseShares\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:46:3-71\nsignature purchaseShares(uint256,uint256)\nvisibility public\nmutability payable"]
-	tags_86 [label="dev: Used to purchase shares"]
-	parameters_87 [label="parameters\nuint256 _shares\nuint256 _id"]
+	tags_87 [label="dev: Used to purchase shares"]
+	parameters_88 [label="parameters\nuint256 _shares\nuint256 _id"]
 	setSellingShares [label="function setSellingShares\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:67:3-74\nsignature setSellingShares(uint256,uint256)\nvisibility public\nmutability nonpayable"]
-	parameters_89 [label="parameters\nuint256 _newSharesToSell\nuint256 _id"]
-	expr_90 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:5-73"]
-	builtins_91 [label="builtin Require\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:5-12"]
+	parameters_90 [label="parameters\nuint256 _newSharesToSell\nuint256 _id"]
+	expr_91 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:5-73"]
+	builtins_92 [label="builtin Require\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:5-12"]
 	equal [label="equal\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:24-26"]
-	cast_93 [label="cast address\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:13-23"]
-	builtins_94 [label="builtin Sender\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:13-23"]
-	storage_load_95 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:27-47"]
-	subscript_96 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:27-47"]
-	storage_var_97 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:27-42"]
-	variable_98 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:43-46"]
+	cast_94 [label="cast address\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:13-23"]
+	builtins_95 [label="builtin Sender\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:13-23"]
+	storage_load_96 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:27-47"]
+	subscript_97 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:27-47"]
+	storage_var_98 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:27-42"]
+	variable_99 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:43-46"]
 	alloc_array [label="alloc array string\ninitializer: 596f7520617265206e6f7420746865206f776e6572\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:49-72"]
 	number_literal [label="uint32 literal: 21\ntests/contract_testcases/solana/doccomments_everywhere.sol:68:49-72"]
-	expr_101 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:5-43"]
-	assign_102 [label="assign\nuint256 storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:25-26"]
-	subscript_103 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:5-24"]
-	storage_var_104 [label="storage variable\nProperty.sellingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:5-19"]
-	variable_105 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:20-23"]
-	variable_106 [label="variable: _newSharesToSell\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:27-43"]
+	expr_102 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:5-43"]
+	assign_103 [label="assign\nuint256 storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:25-26"]
+	subscript_104 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:5-24"]
+	storage_var_105 [label="storage variable\nProperty.sellingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:5-19"]
+	variable_106 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:20-23"]
+	variable_107 [label="variable: _newSharesToSell\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:69:27-43"]
 	setBuyingShares [label="function setBuyingShares\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:72:3-73\nsignature setBuyingShares(uint256,uint256)\nvisibility public\nmutability nonpayable"]
-	parameters_108 [label="parameters\nuint256 _newSharesToSell\nuint256 _id"]
-	expr_109 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:5-73"]
-	builtins_110 [label="builtin Require\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:5-12"]
-	equal_111 [label="equal\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:24-26"]
-	cast_112 [label="cast address\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:13-23"]
-	builtins_113 [label="builtin Sender\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:13-23"]
-	storage_load_114 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:27-47"]
-	subscript_115 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:27-47"]
-	storage_var_116 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:27-42"]
-	variable_117 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:43-46"]
-	alloc_array_118 [label="alloc array string\ninitializer: 596f7520617265206e6f7420746865206f776e6572\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:49-72"]
-	number_literal_119 [label="uint32 literal: 21\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:49-72"]
-	expr_120 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:5-42"]
-	assign_121 [label="assign\nuint256 storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:24-25"]
-	subscript_122 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:5-23"]
-	storage_var_123 [label="storage variable\nProperty.buyingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:5-18"]
-	variable_124 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:19-22"]
-	variable_125 [label="variable: _newSharesToSell\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:26-42"]
+	parameters_109 [label="parameters\nuint256 _newSharesToSell\nuint256 _id"]
+	expr_110 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:5-73"]
+	builtins_111 [label="builtin Require\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:5-12"]
+	equal_112 [label="equal\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:24-26"]
+	cast_113 [label="cast address\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:13-23"]
+	builtins_114 [label="builtin Sender\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:13-23"]
+	storage_load_115 [label="storage load address\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:27-47"]
+	subscript_116 [label="subscript mapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:27-47"]
+	storage_var_117 [label="storage variable\nProperty.tokenDeployers_\nmapping(uint256 => address) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:27-42"]
+	variable_118 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:43-46"]
+	alloc_array_119 [label="alloc array string\ninitializer: 596f7520617265206e6f7420746865206f776e6572\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:49-72"]
+	number_literal_120 [label="uint32 literal: 21\ntests/contract_testcases/solana/doccomments_everywhere.sol:73:49-72"]
+	expr_121 [label="expression\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:5-42"]
+	assign_122 [label="assign\nuint256 storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:24-25"]
+	subscript_123 [label="subscript mapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:5-23"]
+	storage_var_124 [label="storage variable\nProperty.buyingTokens_\nmapping(uint256 => uint256) storage\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:5-18"]
+	variable_125 [label="variable: _id\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:19-22"]
+	variable_126 [label="variable: _newSharesToSell\nuint256\ntests/contract_testcases/solana/doccomments_everywhere.sol:74:26-42"]
 	sellShares [label="function sellShares\ncontract: Property\ntests/contract_testcases/solana/doccomments_everywhere.sol:77:3-59\nsignature sellShares(uint256,uint256)\nvisibility public\nmutability nonpayable"]
-	parameters_127 [label="parameters\nuint256 shares_\nuint256 _id"]
+	parameters_128 [label="parameters\nuint256 shares_\nuint256 _id"]
 	diagnostic [label="pragma ‘solidity’ is ignored\nlevel Debug\ntests/contract_testcases/solana/doccomments_everywhere.sol:1:8-24"]
-	diagnostic_130 [label="library ‘Counters’ not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:6:9-17"]
-	diagnostic_131 [label="found contract ‘Property’\nlevel Debug\ntests/contract_testcases/solana/doccomments_everywhere.sol:4:107-5:19"]
-	diagnostic_132 [label="contract type ‘Counter’ not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:7:12-19"]
-	diagnostic_133 [label="contract ‘ERC1155’ not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:17:17-24"]
-	diagnostic_134 [label="`_tokenIds' is not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:28:29-38"]
-	diagnostic_135 [label="cannot find overloaded function which matches signature\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:52:5-12"]
-	diagnostic_136 [label="cannot find overloaded function which matches signature\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:85:5-12"]
-	diagnostic_137 [label="event 'MintProperty' has never been emitted\nlevel Warning\ntests/contract_testcases/solana/doccomments_everywhere.sol:15:9-21"]
+	diagnostic_131 [label="library ‘Counters’ not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:6:9-17"]
+	diagnostic_132 [label="found contract ‘Property’\nlevel Debug\ntests/contract_testcases/solana/doccomments_everywhere.sol:4:107-5:19"]
+	diagnostic_133 [label="contract type ‘Counter’ not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:7:12-19"]
+	diagnostic_134 [label="contract ‘ERC1155’ not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:17:17-24"]
+	diagnostic_135 [label="`_tokenIds' is not found\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:28:29-38"]
+	diagnostic_136 [label="cannot find overloaded function which matches signature\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:52:5-12"]
+	diagnostic_137 [label="cannot find overloaded function which matches signature\nlevel Error\ntests/contract_testcases/solana/doccomments_everywhere.sol:85:5-12"]
+	diagnostic_138 [label="event 'MintProperty' has never been emitted\nlevel Warning\ntests/contract_testcases/solana/doccomments_everywhere.sol:15:9-21"]
 	events -> MintProperty
 	contracts -> contract
 	contract -> tags [label="tags"]
 	contract -> var [label="variable"]
-	contract -> var_6 [label="variable"]
 	contract -> var_7 [label="variable"]
 	contract -> var_8 [label="variable"]
 	contract -> var_9 [label="variable"]
+	contract -> var_10 [label="variable"]
 	contract -> pricePerShare_ [label="function"]
 	pricePerShare_ -> parameters [label="parameters"]
 	pricePerShare_ -> returns [label="returns"]
@@ -151,122 +151,122 @@ strict digraph "tests/contract_testcases/solana/doccomments_everywhere.sol" {
 	subscript -> storage_var [label="array"]
 	subscript -> func_arg [label="index"]
 	contract -> valueLocked_ [label="function"]
-	valueLocked_ -> parameters_19 [label="parameters"]
-	valueLocked_ -> returns_20 [label="returns"]
-	valueLocked_ -> return_21 [label="body"]
-	return_21 -> storage_load_22 [label="expr"]
-	storage_load_22 -> subscript_23 [label="expr"]
-	subscript_23 -> storage_var_24 [label="array"]
-	subscript_23 -> func_arg_25 [label="index"]
+	valueLocked_ -> parameters_20 [label="parameters"]
+	valueLocked_ -> returns_21 [label="returns"]
+	valueLocked_ -> return_22 [label="body"]
+	return_22 -> storage_load_23 [label="expr"]
+	storage_load_23 -> subscript_24 [label="expr"]
+	subscript_24 -> storage_var_25 [label="array"]
+	subscript_24 -> func_arg_26 [label="index"]
 	contract -> tokenDeployers_ [label="function"]
-	tokenDeployers_ -> parameters_27 [label="parameters"]
-	tokenDeployers_ -> returns_28 [label="returns"]
-	tokenDeployers_ -> return_29 [label="body"]
-	return_29 -> storage_load_30 [label="expr"]
-	storage_load_30 -> subscript_31 [label="expr"]
-	subscript_31 -> storage_var_32 [label="array"]
-	subscript_31 -> func_arg_33 [label="index"]
+	tokenDeployers_ -> parameters_28 [label="parameters"]
+	tokenDeployers_ -> returns_29 [label="returns"]
+	tokenDeployers_ -> return_30 [label="body"]
+	return_30 -> storage_load_31 [label="expr"]
+	storage_load_31 -> subscript_32 [label="expr"]
+	subscript_32 -> storage_var_33 [label="array"]
+	subscript_32 -> func_arg_34 [label="index"]
 	contract -> sellingTokens_ [label="function"]
-	sellingTokens_ -> parameters_35 [label="parameters"]
-	sellingTokens_ -> returns_36 [label="returns"]
-	sellingTokens_ -> return_37 [label="body"]
-	return_37 -> storage_load_38 [label="expr"]
-	storage_load_38 -> subscript_39 [label="expr"]
-	subscript_39 -> storage_var_40 [label="array"]
-	subscript_39 -> func_arg_41 [label="index"]
+	sellingTokens_ -> parameters_36 [label="parameters"]
+	sellingTokens_ -> returns_37 [label="returns"]
+	sellingTokens_ -> return_38 [label="body"]
+	return_38 -> storage_load_39 [label="expr"]
+	storage_load_39 -> subscript_40 [label="expr"]
+	subscript_40 -> storage_var_41 [label="array"]
+	subscript_40 -> func_arg_42 [label="index"]
 	contract -> buyingTokens_ [label="function"]
-	buyingTokens_ -> parameters_43 [label="parameters"]
-	buyingTokens_ -> returns_44 [label="returns"]
-	buyingTokens_ -> return_45 [label="body"]
-	return_45 -> storage_load_46 [label="expr"]
-	storage_load_46 -> subscript_47 [label="expr"]
-	subscript_47 -> storage_var_48 [label="array"]
-	subscript_47 -> func_arg_49 [label="index"]
-	contract -> node_50 [label="constructor"]
-	contract -> node_51 [label="receive"]
-	node_51 -> expr [label="body"]
+	buyingTokens_ -> parameters_44 [label="parameters"]
+	buyingTokens_ -> returns_45 [label="returns"]
+	buyingTokens_ -> return_46 [label="body"]
+	return_46 -> storage_load_47 [label="expr"]
+	storage_load_47 -> subscript_48 [label="expr"]
+	subscript_48 -> storage_var_49 [label="array"]
+	subscript_48 -> func_arg_50 [label="index"]
+	contract -> node_51 [label="constructor"]
+	contract -> node_52 [label="receive"]
+	node_52 -> expr [label="body"]
 	expr -> assign [label="expr"]
-	assign -> subscript_54 [label="left"]
-	subscript_54 -> storage_var_55 [label="array"]
-	subscript_54 -> cast [label="index"]
+	assign -> subscript_55 [label="left"]
+	subscript_55 -> storage_var_56 [label="array"]
+	subscript_55 -> cast [label="index"]
 	cast -> builtins [label="expr"]
 	assign -> add [label="right"]
-	add -> storage_load_59 [label="left"]
-	storage_load_59 -> subscript_60 [label="expr"]
-	subscript_60 -> storage_var_61 [label="array"]
-	subscript_60 -> cast_62 [label="index"]
-	cast_62 -> builtins_63 [label="expr"]
+	add -> storage_load_60 [label="left"]
+	storage_load_60 -> subscript_61 [label="expr"]
+	subscript_61 -> storage_var_62 [label="array"]
+	subscript_61 -> cast_63 [label="index"]
+	cast_63 -> builtins_64 [label="expr"]
 	add -> sign_ext [label="right"]
-	sign_ext -> builtins_65 [label="expr"]
+	sign_ext -> builtins_66 [label="expr"]
 	contract -> mintProperty [label="function"]
-	mintProperty -> parameters_67 [label="parameters"]
+	mintProperty -> parameters_68 [label="parameters"]
 	contract -> getTokenOwner [label="function"]
-	getTokenOwner -> parameters_69 [label="parameters"]
-	getTokenOwner -> returns_70 [label="returns"]
-	getTokenOwner -> return_71 [label="body"]
-	return_71 -> cast_72 [label="expr"]
-	cast_72 -> storage_load_73 [label="expr"]
-	storage_load_73 -> subscript_74 [label="expr"]
-	subscript_74 -> storage_var_75 [label="array"]
-	subscript_74 -> variable [label="index"]
+	getTokenOwner -> parameters_70 [label="parameters"]
+	getTokenOwner -> returns_71 [label="returns"]
+	getTokenOwner -> return_72 [label="body"]
+	return_72 -> cast_73 [label="expr"]
+	cast_73 -> storage_load_74 [label="expr"]
+	storage_load_74 -> subscript_75 [label="expr"]
+	subscript_75 -> storage_var_76 [label="array"]
+	subscript_75 -> variable [label="index"]
 	contract -> getPricePerShare [label="function"]
-	getPricePerShare -> parameters_78 [label="parameters"]
-	getPricePerShare -> returns_79 [label="returns"]
-	getPricePerShare -> return_80 [label="body"]
-	return_80 -> storage_load_81 [label="expr"]
-	storage_load_81 -> subscript_82 [label="expr"]
-	subscript_82 -> storage_var_83 [label="array"]
-	subscript_82 -> variable_84 [label="index"]
+	getPricePerShare -> parameters_79 [label="parameters"]
+	getPricePerShare -> returns_80 [label="returns"]
+	getPricePerShare -> return_81 [label="body"]
+	return_81 -> storage_load_82 [label="expr"]
+	storage_load_82 -> subscript_83 [label="expr"]
+	subscript_83 -> storage_var_84 [label="array"]
+	subscript_83 -> variable_85 [label="index"]
 	contract -> purchaseShares [label="function"]
-	purchaseShares -> tags_86 [label="tags"]
-	purchaseShares -> parameters_87 [label="parameters"]
+	purchaseShares -> tags_87 [label="tags"]
+	purchaseShares -> parameters_88 [label="parameters"]
 	contract -> setSellingShares [label="function"]
-	setSellingShares -> parameters_89 [label="parameters"]
-	setSellingShares -> expr_90 [label="body"]
-	expr_90 -> builtins_91 [label="expr"]
-	builtins_91 -> equal [label="arg #0"]
-	equal -> cast_93 [label="left"]
-	cast_93 -> builtins_94 [label="expr"]
-	equal -> storage_load_95 [label="right"]
-	storage_load_95 -> subscript_96 [label="expr"]
-	subscript_96 -> storage_var_97 [label="array"]
-	subscript_96 -> variable_98 [label="index"]
-	builtins_91 -> alloc_array [label="arg #1"]
+	setSellingShares -> parameters_90 [label="parameters"]
+	setSellingShares -> expr_91 [label="body"]
+	expr_91 -> builtins_92 [label="expr"]
+	builtins_92 -> equal [label="arg #0"]
+	equal -> cast_94 [label="left"]
+	cast_94 -> builtins_95 [label="expr"]
+	equal -> storage_load_96 [label="right"]
+	storage_load_96 -> subscript_97 [label="expr"]
+	subscript_97 -> storage_var_98 [label="array"]
+	subscript_97 -> variable_99 [label="index"]
+	builtins_92 -> alloc_array [label="arg #1"]
 	alloc_array -> number_literal [label="length"]
-	expr_90 -> expr_101 [label="next"]
-	expr_101 -> assign_102 [label="expr"]
-	assign_102 -> subscript_103 [label="left"]
-	subscript_103 -> storage_var_104 [label="array"]
-	subscript_103 -> variable_105 [label="index"]
-	assign_102 -> variable_106 [label="right"]
+	expr_91 -> expr_102 [label="next"]
+	expr_102 -> assign_103 [label="expr"]
+	assign_103 -> subscript_104 [label="left"]
+	subscript_104 -> storage_var_105 [label="array"]
+	subscript_104 -> variable_106 [label="index"]
+	assign_103 -> variable_107 [label="right"]
 	contract -> setBuyingShares [label="function"]
-	setBuyingShares -> parameters_108 [label="parameters"]
-	setBuyingShares -> expr_109 [label="body"]
-	expr_109 -> builtins_110 [label="expr"]
-	builtins_110 -> equal_111 [label="arg #0"]
-	equal_111 -> cast_112 [label="left"]
-	cast_112 -> builtins_113 [label="expr"]
-	equal_111 -> storage_load_114 [label="right"]
-	storage_load_114 -> subscript_115 [label="expr"]
-	subscript_115 -> storage_var_116 [label="array"]
-	subscript_115 -> variable_117 [label="index"]
-	builtins_110 -> alloc_array_118 [label="arg #1"]
-	alloc_array_118 -> number_literal_119 [label="length"]
-	expr_109 -> expr_120 [label="next"]
-	expr_120 -> assign_121 [label="expr"]
-	assign_121 -> subscript_122 [label="left"]
-	subscript_122 -> storage_var_123 [label="array"]
-	subscript_122 -> variable_124 [label="index"]
-	assign_121 -> variable_125 [label="right"]
+	setBuyingShares -> parameters_109 [label="parameters"]
+	setBuyingShares -> expr_110 [label="body"]
+	expr_110 -> builtins_111 [label="expr"]
+	builtins_111 -> equal_112 [label="arg #0"]
+	equal_112 -> cast_113 [label="left"]
+	cast_113 -> builtins_114 [label="expr"]
+	equal_112 -> storage_load_115 [label="right"]
+	storage_load_115 -> subscript_116 [label="expr"]
+	subscript_116 -> storage_var_117 [label="array"]
+	subscript_116 -> variable_118 [label="index"]
+	builtins_111 -> alloc_array_119 [label="arg #1"]
+	alloc_array_119 -> number_literal_120 [label="length"]
+	expr_110 -> expr_121 [label="next"]
+	expr_121 -> assign_122 [label="expr"]
+	assign_122 -> subscript_123 [label="left"]
+	subscript_123 -> storage_var_124 [label="array"]
+	subscript_123 -> variable_125 [label="index"]
+	assign_122 -> variable_126 [label="right"]
 	contract -> sellShares [label="function"]
-	sellShares -> parameters_127 [label="parameters"]
+	sellShares -> parameters_128 [label="parameters"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_130 [label="Error"]
-	diagnostics -> diagnostic_131 [label="Debug"]
-	diagnostics -> diagnostic_132 [label="Error"]
+	diagnostics -> diagnostic_131 [label="Error"]
+	diagnostics -> diagnostic_132 [label="Debug"]
 	diagnostics -> diagnostic_133 [label="Error"]
 	diagnostics -> diagnostic_134 [label="Error"]
 	diagnostics -> diagnostic_135 [label="Error"]
 	diagnostics -> diagnostic_136 [label="Error"]
-	diagnostics -> diagnostic_137 [label="Warning"]
+	diagnostics -> diagnostic_137 [label="Error"]
+	diagnostics -> diagnostic_138 [label="Warning"]
 }

+ 14 - 14
tests/contract_testcases/solana/event.dot

@@ -3,23 +3,22 @@ strict digraph "tests/contract_testcases/solana/event.sol" {
 	contract [label="contract c\ntests/contract_testcases/solana/event.sol:4:1-5:12"]
 	foo [label="function foo\ncontract: c\ntests/contract_testcases/solana/event.sol:6:5-26\nsignature foo()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘c’\nlevel Debug\ntests/contract_testcases/solana/event.sol:4:1-5:12"]
-	diagnostic_7 [label="`a' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:7:18-19"]
-	diagnostic_8 [label="`b' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:7:21-22"]
-	diagnostic_9 [label="`a' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:8:24-25"]
-	diagnostic_10 [label="`b' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:8:33-34"]
-	diagnostic_11 [label="duplicate argument with name ‘no’\nlevel Error\ntests/contract_testcases/solana/event.sol:8:36-38"]
-	diagnostic_12 [label="`c' is a contract\nlevel Error\ntests/contract_testcases/solana/event.sol:8:40-41"]
-	diagnostic_13 [label="event ‘Foo2’ not found\nlevel Error\ntests/contract_testcases/solana/event.sol:9:14-18"]
-	diagnostic_14 [label="`a' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:9:25-26"]
-	diagnostic_15 [label="`b' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:9:34-35"]
-	diagnostic_16 [label="duplicate argument with name ‘no’\nlevel Error\ntests/contract_testcases/solana/event.sol:9:37-39"]
-	diagnostic_17 [label="`c' is a contract\nlevel Error\ntests/contract_testcases/solana/event.sol:9:41-42"]
-	diagnostic_18 [label="event 'Foo' has never been emitted\nlevel Warning\ntests/contract_testcases/solana/event.sol:3:7-10"]
+	diagnostic_8 [label="`a' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:7:18-19"]
+	diagnostic_9 [label="`b' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:7:21-22"]
+	diagnostic_10 [label="`a' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:8:24-25"]
+	diagnostic_11 [label="`b' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:8:33-34"]
+	diagnostic_12 [label="duplicate argument with name ‘no’\nlevel Error\ntests/contract_testcases/solana/event.sol:8:36-38"]
+	diagnostic_13 [label="`c' is a contract\nlevel Error\ntests/contract_testcases/solana/event.sol:8:40-41"]
+	diagnostic_14 [label="event ‘Foo2’ not found\nlevel Error\ntests/contract_testcases/solana/event.sol:9:14-18"]
+	diagnostic_15 [label="`a' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:9:25-26"]
+	diagnostic_16 [label="`b' is not found\nlevel Error\ntests/contract_testcases/solana/event.sol:9:34-35"]
+	diagnostic_17 [label="duplicate argument with name ‘no’\nlevel Error\ntests/contract_testcases/solana/event.sol:9:37-39"]
+	diagnostic_18 [label="`c' is a contract\nlevel Error\ntests/contract_testcases/solana/event.sol:9:41-42"]
+	diagnostic_19 [label="event 'Foo' has never been emitted\nlevel Warning\ntests/contract_testcases/solana/event.sol:3:7-10"]
 	events -> Foo
 	contracts -> contract
 	contract -> foo [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
 	diagnostics -> diagnostic_8 [label="Error"]
 	diagnostics -> diagnostic_9 [label="Error"]
 	diagnostics -> diagnostic_10 [label="Error"]
@@ -30,5 +29,6 @@ strict digraph "tests/contract_testcases/solana/event.sol" {
 	diagnostics -> diagnostic_15 [label="Error"]
 	diagnostics -> diagnostic_16 [label="Error"]
 	diagnostics -> diagnostic_17 [label="Error"]
-	diagnostics -> diagnostic_18 [label="Warning"]
+	diagnostics -> diagnostic_18 [label="Error"]
+	diagnostics -> diagnostic_19 [label="Warning"]
 }

+ 20 - 20
tests/contract_testcases/solana/expressions/bytes32_0.dot

@@ -7,17 +7,17 @@ strict digraph "tests/contract_testcases/solana/expressions/bytes32_0.sol" {
 	variable [label="variable: r\nbytes32\ntests/contract_testcases/solana/expressions/bytes32_0.sol:4:17-18"]
 	number_literal [label="bytes32 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0.sol:4:21-31"]
 	b4 [label="function b4\ncontract: x\ntests/contract_testcases/solana/expressions/bytes32_0.sol:7:13-57\nsignature b4()\nvisibility public\nmutability pure"]
-	returns_9 [label="returns\nbytes4 r"]
-	expr_10 [label="expression\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:17-39"]
-	assign_11 [label="assign\nbytes4\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:19-20"]
-	variable_12 [label="variable: r\nbytes4\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:17-18"]
-	number_literal_13 [label="bytes4 literal: 3405700781\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:21-39"]
+	returns_10 [label="returns\nbytes4 r"]
+	expr_11 [label="expression\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:17-39"]
+	assign_12 [label="assign\nbytes4\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:19-20"]
+	variable_13 [label="variable: r\nbytes4\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:17-18"]
+	number_literal_14 [label="bytes4 literal: 3405700781\ntests/contract_testcases/solana/expressions/bytes32_0.sol:8:21-39"]
 	b3 [label="function b3\ncontract: x\ntests/contract_testcases/solana/expressions/bytes32_0.sol:11:13-57\nsignature b3()\nvisibility public\nmutability pure"]
-	returns_15 [label="returns\nbytes3 r"]
-	expr_16 [label="expression\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:17-37"]
-	assign_17 [label="assign\nbytes3\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:19-20"]
-	variable_18 [label="variable: r\nbytes3\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:17-18"]
-	number_literal_19 [label="bytes3 literal: 74291\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:21-37"]
+	returns_16 [label="returns\nbytes3 r"]
+	expr_17 [label="expression\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:17-37"]
+	assign_18 [label="assign\nbytes3\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:19-20"]
+	variable_19 [label="variable: r\nbytes3\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:17-18"]
+	number_literal_20 [label="bytes3 literal: 74291\ntests/contract_testcases/solana/expressions/bytes32_0.sol:12:21-37"]
 	diagnostic [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/expressions/bytes32_0.sol:2:9-20"]
 	contracts -> contract
 	contract -> b32 [label="function"]
@@ -27,16 +27,16 @@ strict digraph "tests/contract_testcases/solana/expressions/bytes32_0.sol" {
 	assign -> variable [label="left"]
 	assign -> number_literal [label="right"]
 	contract -> b4 [label="function"]
-	b4 -> returns_9 [label="returns"]
-	b4 -> expr_10 [label="body"]
-	expr_10 -> assign_11 [label="expr"]
-	assign_11 -> variable_12 [label="left"]
-	assign_11 -> number_literal_13 [label="right"]
+	b4 -> returns_10 [label="returns"]
+	b4 -> expr_11 [label="body"]
+	expr_11 -> assign_12 [label="expr"]
+	assign_12 -> variable_13 [label="left"]
+	assign_12 -> number_literal_14 [label="right"]
 	contract -> b3 [label="function"]
-	b3 -> returns_15 [label="returns"]
-	b3 -> expr_16 [label="body"]
-	expr_16 -> assign_17 [label="expr"]
-	assign_17 -> variable_18 [label="left"]
-	assign_17 -> number_literal_19 [label="right"]
+	b3 -> returns_16 [label="returns"]
+	b3 -> expr_17 [label="body"]
+	expr_17 -> assign_18 [label="expr"]
+	assign_18 -> variable_19 [label="left"]
+	assign_18 -> number_literal_20 [label="right"]
 	diagnostics -> diagnostic [label="Debug"]
 }

+ 2 - 2
tests/contract_testcases/solana/expressions/bytes32_0_01.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/expressions/bytes32_0_01.sol" {
 	b32 [label="function b32\ncontract: foo\ntests/contract_testcases/solana/expressions/bytes32_0_01.sol:3:13-59\nsignature b32()\nvisibility public\nmutability pure"]
 	returns [label="returns\nbytes32 r"]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/bytes32_0_01.sol:2:9-22"]
-	diagnostic_6 [label="number of 2 bytes cannot be converted to type ‘bytes32’\nlevel Error\ntests/contract_testcases/solana/expressions/bytes32_0_01.sol:4:21-36"]
+	diagnostic_7 [label="number of 2 bytes cannot be converted to type ‘bytes32’\nlevel Error\ntests/contract_testcases/solana/expressions/bytes32_0_01.sol:4:21-36"]
 	contracts -> contract
 	contract -> b32 [label="function"]
 	b32 -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }

+ 52 - 52
tests/contract_testcases/solana/expressions/bytes32_0_02.dot

@@ -2,81 +2,81 @@ strict digraph "tests/contract_testcases/solana/expressions/bytes32_0_02.sol" {
 	contract [label="contract foo\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:2:9-22"]
 	var [label="variable x\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:3:13-36"]
 	number_literal [label="bytes32 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:3:32-36"]
-	var_4 [label="variable y\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:4:13-42"]
-	number_literal_5 [label="bytes32 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:4:32-42"]
-	var_6 [label="variable z1\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:5:13-42"]
-	number_literal_7 [label="bytes3 literal: 1048576\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:5:32-42"]
-	var_8 [label="variable z2\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:7:13-42"]
-	number_literal_9 [label="bytes3 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:7:32-42"]
-	var_10 [label="variable z3\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:9:13-45"]
-	number_literal_11 [label="bytes3 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:9:32-45"]
+	var_5 [label="variable y\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:4:13-42"]
+	number_literal_6 [label="bytes32 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:4:32-42"]
+	var_7 [label="variable z1\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:5:13-42"]
+	number_literal_8 [label="bytes3 literal: 1048576\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:5:32-42"]
+	var_9 [label="variable z2\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:7:13-42"]
+	number_literal_10 [label="bytes3 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:7:32-42"]
+	var_11 [label="variable z3\nvisibility public\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:9:13-45"]
+	number_literal_12 [label="bytes3 literal: 0\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:9:32-45"]
 	x [label="function x\ncontract: foo\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:3:28-29\nsignature x()\nvisibility public\nmutability view"]
 	returns [label="returns\nbytes32 "]
 	return [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
 	storage_load [label="storage load bytes32\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
 	storage_var [label="storage variable\nfoo.x\nbytes32 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
 	y [label="function y\ncontract: foo\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:4:28-29\nsignature y()\nvisibility public\nmutability view"]
-	returns_18 [label="returns\nbytes32 "]
-	return_19 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_load_20 [label="storage load bytes32\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_var_21 [label="storage variable\nfoo.y\nbytes32 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	returns_19 [label="returns\nbytes32 "]
+	return_20 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_load_21 [label="storage load bytes32\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_var_22 [label="storage variable\nfoo.y\nbytes32 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
 	z1 [label="function z1\ncontract: foo\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:5:27-29\nsignature z1()\nvisibility public\nmutability view"]
-	returns_23 [label="returns\nbytes3 "]
-	return_24 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_load_25 [label="storage load bytes3\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_var_26 [label="storage variable\nfoo.z1\nbytes3 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	returns_24 [label="returns\nbytes3 "]
+	return_25 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_load_26 [label="storage load bytes3\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_var_27 [label="storage variable\nfoo.z1\nbytes3 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
 	z2 [label="function z2\ncontract: foo\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:7:27-29\nsignature z2()\nvisibility public\nmutability view"]
-	returns_28 [label="returns\nbytes3 "]
-	return_29 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_load_30 [label="storage load bytes3\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_var_31 [label="storage variable\nfoo.z2\nbytes3 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	returns_29 [label="returns\nbytes3 "]
+	return_30 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_load_31 [label="storage load bytes3\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_var_32 [label="storage variable\nfoo.z2\nbytes3 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
 	z3 [label="function z3\ncontract: foo\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:9:27-29\nsignature z3()\nvisibility public\nmutability view"]
-	returns_33 [label="returns\nbytes3 "]
-	return_34 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_load_35 [label="storage load bytes3\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
-	storage_var_36 [label="storage variable\nfoo.z3\nbytes3 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	returns_34 [label="returns\nbytes3 "]
+	return_35 [label="return\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_load_36 [label="storage load bytes3\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
+	storage_var_37 [label="storage variable\nfoo.z3\nbytes3 storage\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:1:1"]
 	b32 [label="function b32\ncontract: foo\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:11:13-59\nsignature b32()\nvisibility public\nmutability pure"]
-	returns_38 [label="returns\nbytes32 r"]
+	returns_39 [label="returns\nbytes32 r"]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:2:9-22"]
-	diagnostic_41 [label="negative number cannot be converted to type ‘bytes32’\nlevel Error\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:12:21-32"]
+	diagnostic_42 [label="negative number cannot be converted to type ‘bytes32’\nlevel Error\ntests/contract_testcases/solana/expressions/bytes32_0_02.sol:12:21-32"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
-	contract -> var_4 [label="variable"]
-	var_4 -> number_literal_5 [label="initializer"]
-	contract -> var_6 [label="variable"]
-	var_6 -> number_literal_7 [label="initializer"]
-	contract -> var_8 [label="variable"]
-	var_8 -> number_literal_9 [label="initializer"]
-	contract -> var_10 [label="variable"]
-	var_10 -> number_literal_11 [label="initializer"]
+	contract -> var_5 [label="variable"]
+	var_5 -> number_literal_6 [label="initializer"]
+	contract -> var_7 [label="variable"]
+	var_7 -> number_literal_8 [label="initializer"]
+	contract -> var_9 [label="variable"]
+	var_9 -> number_literal_10 [label="initializer"]
+	contract -> var_11 [label="variable"]
+	var_11 -> number_literal_12 [label="initializer"]
 	contract -> x [label="function"]
 	x -> returns [label="returns"]
 	x -> return [label="body"]
 	return -> storage_load [label="expr"]
 	storage_load -> storage_var [label="expr"]
 	contract -> y [label="function"]
-	y -> returns_18 [label="returns"]
-	y -> return_19 [label="body"]
-	return_19 -> storage_load_20 [label="expr"]
-	storage_load_20 -> storage_var_21 [label="expr"]
+	y -> returns_19 [label="returns"]
+	y -> return_20 [label="body"]
+	return_20 -> storage_load_21 [label="expr"]
+	storage_load_21 -> storage_var_22 [label="expr"]
 	contract -> z1 [label="function"]
-	z1 -> returns_23 [label="returns"]
-	z1 -> return_24 [label="body"]
-	return_24 -> storage_load_25 [label="expr"]
-	storage_load_25 -> storage_var_26 [label="expr"]
+	z1 -> returns_24 [label="returns"]
+	z1 -> return_25 [label="body"]
+	return_25 -> storage_load_26 [label="expr"]
+	storage_load_26 -> storage_var_27 [label="expr"]
 	contract -> z2 [label="function"]
-	z2 -> returns_28 [label="returns"]
-	z2 -> return_29 [label="body"]
-	return_29 -> storage_load_30 [label="expr"]
-	storage_load_30 -> storage_var_31 [label="expr"]
+	z2 -> returns_29 [label="returns"]
+	z2 -> return_30 [label="body"]
+	return_30 -> storage_load_31 [label="expr"]
+	storage_load_31 -> storage_var_32 [label="expr"]
 	contract -> z3 [label="function"]
-	z3 -> returns_33 [label="returns"]
-	z3 -> return_34 [label="body"]
-	return_34 -> storage_load_35 [label="expr"]
-	storage_load_35 -> storage_var_36 [label="expr"]
+	z3 -> returns_34 [label="returns"]
+	z3 -> return_35 [label="body"]
+	return_35 -> storage_load_36 [label="expr"]
+	storage_load_36 -> storage_var_37 [label="expr"]
 	contract -> b32 [label="function"]
-	b32 -> returns_38 [label="returns"]
+	b32 -> returns_39 [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_41 [label="Error"]
+	diagnostics -> diagnostic_42 [label="Error"]
 }

+ 5 - 5
tests/contract_testcases/solana/expressions/const_in_type.dot

@@ -6,10 +6,10 @@ strict digraph "tests/contract_testcases/solana/expressions/const_in_type.sol" {
 	returns [label="returns\nuint256 "]
 	return [label="return\ntests/contract_testcases/solana/expressions/const_in_type.sol:1:1"]
 	constant [label="constant variable\nx.Y\nuint256\ntests/contract_testcases/solana/expressions/const_in_type.sol:1:1"]
-	node_8 [label="constructor \ncontract: x\ntests/contract_testcases/solana/expressions/const_in_type.sol:5:13-48\nsignature (bytes32[24])\nvisibility public\nmutability nonpayable"]
+	node_9 [label="constructor \ncontract: x\ntests/contract_testcases/solana/expressions/const_in_type.sol:5:13-48\nsignature (bytes32[24])\nvisibility public\nmutability nonpayable"]
 	parameters [label="parameters\nbytes32[24] foo"]
 	diagnostic [label="found contract ‘x’\nlevel Debug\ntests/contract_testcases/solana/expressions/const_in_type.sol:2:9-20"]
-	diagnostic_12 [label="function parameter 'foo' has never been read\nlevel Warning\ntests/contract_testcases/solana/expressions/const_in_type.sol:5:43-46"]
+	diagnostic_13 [label="function parameter 'foo' has never been read\nlevel Warning\ntests/contract_testcases/solana/expressions/const_in_type.sol:5:43-46"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
@@ -17,8 +17,8 @@ strict digraph "tests/contract_testcases/solana/expressions/const_in_type.sol" {
 	Y -> returns [label="returns"]
 	Y -> return [label="body"]
 	return -> constant [label="expr"]
-	contract -> node_8 [label="constructor"]
-	node_8 -> parameters [label="parameters"]
+	contract -> node_9 [label="constructor"]
+	node_9 -> parameters [label="parameters"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_12 [label="Warning"]
+	diagnostics -> diagnostic_13 [label="Warning"]
 }

+ 19 - 19
tests/contract_testcases/solana/expressions/contract_compare.dot

@@ -6,18 +6,18 @@ strict digraph "tests/contract_testcases/solana/expressions/contract_compare.sol
 	return [label="return\ntests/contract_testcases/solana/expressions/contract_compare.sol:4:3-22"]
 	less [label="less\ntests/contract_testcases/solana/expressions/contract_compare.sol:4:15-16"]
 	variable [label="variable: left\ncontract d\ntests/contract_testcases/solana/expressions/contract_compare.sol:4:10-14"]
-	variable_8 [label="variable: right\ncontract d\ntests/contract_testcases/solana/expressions/contract_compare.sol:4:17-22"]
-	cmp_9 [label="function cmp\ncontract: c\ntests/contract_testcases/solana/expressions/contract_compare.sol:7:2-53\nsignature cmp(bytes32,bytes32)\nvisibility public\nmutability nonpayable"]
-	parameters_10 [label="parameters\ncontract d left\ncontract e right"]
-	returns_11 [label="returns\nbool "]
-	contract_12 [label="contract d\ntests/contract_testcases/solana/expressions/contract_compare.sol:12:1-13:12"]
-	contract_13 [label="contract e\ntests/contract_testcases/solana/expressions/contract_compare.sol:13:14-14:12"]
+	variable_9 [label="variable: right\ncontract d\ntests/contract_testcases/solana/expressions/contract_compare.sol:4:17-22"]
+	cmp_10 [label="function cmp\ncontract: c\ntests/contract_testcases/solana/expressions/contract_compare.sol:7:2-53\nsignature cmp(bytes32,bytes32)\nvisibility public\nmutability nonpayable"]
+	parameters_11 [label="parameters\ncontract d left\ncontract e right"]
+	returns_12 [label="returns\nbool "]
+	contract_13 [label="contract d\ntests/contract_testcases/solana/expressions/contract_compare.sol:12:1-13:12"]
+	contract_14 [label="contract e\ntests/contract_testcases/solana/expressions/contract_compare.sol:13:14-14:12"]
 	diagnostic [label="found contract ‘c’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_compare.sol:1:1-2:12"]
-	diagnostic_16 [label="found contract ‘d’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_compare.sol:12:1-13:12"]
-	diagnostic_17 [label="found contract ‘e’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_compare.sol:13:14-14:12"]
-	diagnostic_18 [label="function ‘cmp’ overrides function in same contract\nlevel Error\ntests/contract_testcases/solana/expressions/contract_compare.sol:7:2-53"]
+	diagnostic_17 [label="found contract ‘d’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_compare.sol:12:1-13:12"]
+	diagnostic_18 [label="found contract ‘e’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_compare.sol:13:14-14:12"]
+	diagnostic_19 [label="function ‘cmp’ overrides function in same contract\nlevel Error\ntests/contract_testcases/solana/expressions/contract_compare.sol:7:2-53"]
 	note [label="previous definition of ‘cmp’\ntests/contract_testcases/solana/expressions/contract_compare.sol:3:2-53"]
-	diagnostic_20 [label="expression of type contract d not allowed\nlevel Error\ntests/contract_testcases/solana/expressions/contract_compare.sol:8:10-14"]
+	diagnostic_21 [label="expression of type contract d not allowed\nlevel Error\ntests/contract_testcases/solana/expressions/contract_compare.sol:8:10-14"]
 	contracts -> contract
 	contract -> cmp [label="function"]
 	cmp -> parameters [label="parameters"]
@@ -25,16 +25,16 @@ strict digraph "tests/contract_testcases/solana/expressions/contract_compare.sol
 	cmp -> return [label="body"]
 	return -> less [label="expr"]
 	less -> variable [label="left"]
-	less -> variable_8 [label="right"]
-	contract -> cmp_9 [label="function"]
-	cmp_9 -> parameters_10 [label="parameters"]
-	cmp_9 -> returns_11 [label="returns"]
-	contracts -> contract_12
+	less -> variable_9 [label="right"]
+	contract -> cmp_10 [label="function"]
+	cmp_10 -> parameters_11 [label="parameters"]
+	cmp_10 -> returns_12 [label="returns"]
 	contracts -> contract_13
+	contracts -> contract_14
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_16 [label="Debug"]
 	diagnostics -> diagnostic_17 [label="Debug"]
-	diagnostics -> diagnostic_18 [label="Error"]
-	diagnostic_18 -> note [label="note"]
-	diagnostics -> diagnostic_20 [label="Error"]
+	diagnostics -> diagnostic_18 [label="Debug"]
+	diagnostics -> diagnostic_19 [label="Error"]
+	diagnostic_19 -> note [label="note"]
+	diagnostics -> diagnostic_21 [label="Error"]
 }

+ 19 - 19
tests/contract_testcases/solana/expressions/contract_no_init.dot

@@ -6,28 +6,28 @@ strict digraph "tests/contract_testcases/solana/expressions/contract_no_init.sol
 	return [label="return\ntests/contract_testcases/solana/expressions/contract_no_init.sol:1:1"]
 	storage_load [label="storage load int256\ntests/contract_testcases/solana/expressions/contract_no_init.sol:1:1"]
 	storage_var [label="storage variable\nother.a\nint256 storage\ntests/contract_testcases/solana/expressions/contract_no_init.sol:1:1"]
-	contract_8 [label="contract testing\ntests/contract_testcases/solana/expressions/contract_no_init.sol:6:9-26"]
+	contract_9 [label="contract testing\ntests/contract_testcases/solana/expressions/contract_no_init.sol:6:9-26"]
 	test [label="function test\ncontract: testing\ntests/contract_testcases/solana/expressions/contract_no_init.sol:7:13-54\nsignature test(int256)\nvisibility public\nmutability nonpayable"]
 	parameters [label="parameters\nint256 x"]
-	returns_11 [label="returns\nint256 "]
+	returns_12 [label="returns\nint256 "]
 	var_decl [label="variable decl contract other o\ntests/contract_testcases/solana/expressions/contract_no_init.sol:8:17-24"]
 	dowhile [label="do while\ntests/contract_testcases/solana/expressions/contract_no_init.sol:9:17-12:30"]
 	expr [label="expression\ntests/contract_testcases/solana/expressions/contract_no_init.sol:10:21-24"]
 	post_decrement [label="post decrement\nint256\ntests/contract_testcases/solana/expressions/contract_no_init.sol:10:21-24"]
 	variable [label="variable: x\nint256\ntests/contract_testcases/solana/expressions/contract_no_init.sol:10:21-22"]
-	expr_17 [label="expression\ntests/contract_testcases/solana/expressions/contract_no_init.sol:11:21-36"]
+	expr_18 [label="expression\ntests/contract_testcases/solana/expressions/contract_no_init.sol:11:21-36"]
 	assign [label="assign\ncontract other\ntests/contract_testcases/solana/expressions/contract_no_init.sol:11:23-24"]
-	variable_19 [label="variable: o\ncontract other\ntests/contract_testcases/solana/expressions/contract_no_init.sol:11:21-22"]
+	variable_20 [label="variable: o\ncontract other\ntests/contract_testcases/solana/expressions/contract_no_init.sol:11:21-22"]
 	constructor [label="constructor contract other\ntests/contract_testcases/solana/expressions/contract_no_init.sol:11:25-36"]
 	more [label="more\ntests/contract_testcases/solana/expressions/contract_no_init.sol:12:26-27"]
-	variable_22 [label="variable: x\nint256\ntests/contract_testcases/solana/expressions/contract_no_init.sol:12:24-25"]
+	variable_23 [label="variable: x\nint256\ntests/contract_testcases/solana/expressions/contract_no_init.sol:12:24-25"]
 	number_literal [label="int256 literal: 0\ntests/contract_testcases/solana/expressions/contract_no_init.sol:12:28-29"]
-	return_24 [label="return\ntests/contract_testcases/solana/expressions/contract_no_init.sol:14:17-29"]
+	return_25 [label="return\ntests/contract_testcases/solana/expressions/contract_no_init.sol:14:17-29"]
 	call_external_function [label="call external function\ntests/contract_testcases/solana/expressions/contract_no_init.sol:14:24-29"]
 	external_function [label="function() external view returns (int256)\nother.a\ntests/contract_testcases/solana/expressions/contract_no_init.sol:14:24-29"]
-	variable_27 [label="variable: o\ncontract other\ntests/contract_testcases/solana/expressions/contract_no_init.sol:14:24-25"]
+	variable_28 [label="variable: o\ncontract other\ntests/contract_testcases/solana/expressions/contract_no_init.sol:14:24-25"]
 	diagnostic [label="found contract ‘other’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_no_init.sol:2:9-24"]
-	diagnostic_30 [label="found contract ‘testing’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_no_init.sol:6:9-26"]
+	diagnostic_31 [label="found contract ‘testing’\nlevel Debug\ntests/contract_testcases/solana/expressions/contract_no_init.sol:6:9-26"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> a [label="function"]
@@ -35,26 +35,26 @@ strict digraph "tests/contract_testcases/solana/expressions/contract_no_init.sol
 	a -> return [label="body"]
 	return -> storage_load [label="expr"]
 	storage_load -> storage_var [label="expr"]
-	contracts -> contract_8
-	contract_8 -> test [label="function"]
+	contracts -> contract_9
+	contract_9 -> test [label="function"]
 	test -> parameters [label="parameters"]
-	test -> returns_11 [label="returns"]
+	test -> returns_12 [label="returns"]
 	test -> var_decl [label="body"]
 	var_decl -> dowhile [label="next"]
 	dowhile -> expr [label="body"]
 	expr -> post_decrement [label="expr"]
 	post_decrement -> variable [label="expr"]
-	expr -> expr_17 [label="next"]
-	expr_17 -> assign [label="expr"]
-	assign -> variable_19 [label="left"]
+	expr -> expr_18 [label="next"]
+	expr_18 -> assign [label="expr"]
+	assign -> variable_20 [label="left"]
 	assign -> constructor [label="right"]
 	dowhile -> more [label="cond"]
-	more -> variable_22 [label="left"]
+	more -> variable_23 [label="left"]
 	more -> number_literal [label="right"]
-	dowhile -> return_24 [label="next"]
-	return_24 -> call_external_function [label="expr"]
+	dowhile -> return_25 [label="next"]
+	return_25 -> call_external_function [label="expr"]
 	call_external_function -> external_function [label="function"]
-	external_function -> variable_27 [label="address"]
+	external_function -> variable_28 [label="address"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_30 [label="Debug"]
+	diagnostics -> diagnostic_31 [label="Debug"]
 }

+ 2 - 2
tests/contract_testcases/solana/expressions/interfaceid.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/expressions/interfaceid.sol" {
 	get [label="function get\ncontract: foo\ntests/contract_testcases/solana/expressions/interfaceid.sol:3:13-51\nsignature get()\nvisibility public\nmutability nonpayable"]
 	returns [label="returns\nbytes4 "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/interfaceid.sol:2:9-22"]
-	diagnostic_6 [label="type(…).interfaceId is permitted on interface, not contract foo\nlevel Error\ntests/contract_testcases/solana/expressions/interfaceid.sol:4:24-45"]
+	diagnostic_7 [label="type(…).interfaceId is permitted on interface, not contract foo\nlevel Error\ntests/contract_testcases/solana/expressions/interfaceid.sol:4:24-45"]
 	contracts -> contract
 	contract -> get [label="function"]
 	get -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/expressions/pushpop.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/solana/expressions/pushpop.sol" {
 	contract [label="contract foo\ntests/contract_testcases/solana/expressions/pushpop.sol:2:9-22"]
 	test [label="function test\ncontract: foo\ntests/contract_testcases/solana/expressions/pushpop.sol:3:13-35\nsignature test()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/pushpop.sol:2:9-22"]
-	diagnostic_5 [label="‘push()’ not supported on ‘bytes’ on target solana\nlevel Error\ntests/contract_testcases/solana/expressions/pushpop.sol:6:19-23"]
+	diagnostic_6 [label="‘push()’ not supported on ‘bytes’ on target solana\nlevel Error\ntests/contract_testcases/solana/expressions/pushpop.sol:6:19-23"]
 	contracts -> contract
 	contract -> test [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/expressions/pushpop_01.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/solana/expressions/pushpop_01.sol" {
 	contract [label="contract foo\ntests/contract_testcases/solana/expressions/pushpop_01.sol:2:9-22"]
 	test [label="function test\ncontract: foo\ntests/contract_testcases/solana/expressions/pushpop_01.sol:3:13-35\nsignature test()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/pushpop_01.sol:2:9-22"]
-	diagnostic_5 [label="‘pop()’ not supported on ‘bytes’ on target solana\nlevel Error\ntests/contract_testcases/solana/expressions/pushpop_01.sol:6:19-22"]
+	diagnostic_6 [label="‘pop()’ not supported on ‘bytes’ on target solana\nlevel Error\ntests/contract_testcases/solana/expressions/pushpop_01.sol:6:19-22"]
 	contracts -> contract
 	contract -> test [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }

+ 6 - 6
tests/contract_testcases/solana/expressions/selector_in_free_function.dot

@@ -2,15 +2,15 @@ strict digraph "tests/contract_testcases/solana/expressions/selector_in_free_fun
 	contract [label="contract I\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:2:9-21"]
 	X [label="function X\ncontract: I\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:3:13-39\nsignature X(bytes)\nvisibility external\nmutability nonpayable\nvirtual"]
 	parameters [label="parameters\nbytes "]
-	contract_4 [label="contract foo\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-22"]
+	contract_5 [label="contract foo\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-22"]
 	diagnostic [label="found interface ‘I’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:2:9-21"]
-	diagnostic_7 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-22"]
-	diagnostic_8 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:6:9-38"]
+	diagnostic_8 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-22"]
+	diagnostic_9 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:6:9-38"]
 	contracts -> contract
 	contract -> X [label="function"]
 	X -> parameters [label="parameters"]
-	contracts -> contract_4
+	contracts -> contract_5
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Warning"]
+	diagnostics -> diagnostic_8 [label="Debug"]
+	diagnostics -> diagnostic_9 [label="Warning"]
 }

+ 10 - 10
tests/contract_testcases/solana/expressions/selector_in_free_function_01.dot

@@ -2,29 +2,29 @@ strict digraph "tests/contract_testcases/solana/expressions/selector_in_free_fun
 	contract [label="contract I\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:2:9-21"]
 	X [label="function X\ncontract: I\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:3:13-39\nsignature X(bytes)\nvisibility external\nmutability nonpayable\nvirtual"]
 	parameters [label="parameters\nbytes "]
-	contract_4 [label="contract X\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:6:9-20"]
+	contract_5 [label="contract X\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:6:9-20"]
 	x [label="function x\ncontract: X\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:7:13-49\nsignature x()\nvisibility public\nmutability nonpayable"]
 	returns [label="returns\nbytes4 "]
 	return [label="return\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:8:17-36"]
 	builtins [label="builtin FunctionSelector\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:8:24-27"]
 	internal_function [label="function(bytes) internal returns (void)\nI.X\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:8:24-25"]
 	diagnostic [label="found interface ‘I’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:2:9-21"]
-	diagnostic_12 [label="X is already defined as a contract name\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:3:22-23"]
+	diagnostic_13 [label="X is already defined as a contract name\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:3:22-23"]
 	note [label="location of previous definition\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:6:9-20"]
-	diagnostic_14 [label="found contract ‘X’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:6:9-20"]
-	diagnostic_15 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:7:13-49"]
+	diagnostic_15 [label="found contract ‘X’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:6:9-20"]
+	diagnostic_16 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_01.sol:7:13-49"]
 	contracts -> contract
 	contract -> X [label="function"]
 	X -> parameters [label="parameters"]
-	contracts -> contract_4
-	contract_4 -> x [label="function"]
+	contracts -> contract_5
+	contract_5 -> x [label="function"]
 	x -> returns [label="returns"]
 	x -> return [label="body"]
 	return -> builtins [label="expr"]
 	builtins -> internal_function [label="arg #0"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_12 [label="Warning"]
-	diagnostic_12 -> note [label="note"]
-	diagnostics -> diagnostic_14 [label="Debug"]
-	diagnostics -> diagnostic_15 [label="Warning"]
+	diagnostics -> diagnostic_13 [label="Warning"]
+	diagnostic_13 -> note [label="note"]
+	diagnostics -> diagnostic_15 [label="Debug"]
+	diagnostics -> diagnostic_16 [label="Warning"]
 }

+ 9 - 9
tests/contract_testcases/solana/expressions/selector_in_free_function_02.dot

@@ -1,7 +1,7 @@
 strict digraph "tests/contract_testcases/solana/expressions/selector_in_free_function_02.sol" {
 	contract [label="contract I\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:2:9-20"]
 	X [label="function X\ncontract: I\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:3:13-34\nsignature X()\nvisibility external\nmutability nonpayable"]
-	contract_3 [label="contract foo\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:6:9-22"]
+	contract_4 [label="contract foo\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:6:9-22"]
 	f [label="function f\ncontract: foo\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:7:13-52\nsignature f(bytes32)\nvisibility public\nmutability nonpayable"]
 	parameters [label="parameters\ncontract I t"]
 	returns [label="returns\nbytes4 "]
@@ -10,14 +10,14 @@ strict digraph "tests/contract_testcases/solana/expressions/selector_in_free_fun
 	external_function [label="function() external\nI.X\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:8:26-27"]
 	variable [label="variable: t\ncontract I\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:8:24-25"]
 	diagnostic [label="found contract ‘I’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:2:9-20"]
-	diagnostic_13 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:6:9-22"]
-	diagnostic_14 [label="function parameter 't' has never been read\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:7:26-27"]
-	diagnostic_15 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:3:13-34"]
-	diagnostic_16 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:7:13-52"]
+	diagnostic_14 [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:6:9-22"]
+	diagnostic_15 [label="function parameter 't' has never been read\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:7:26-27"]
+	diagnostic_16 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:3:13-34"]
+	diagnostic_17 [label="function can be declared ‘pure’\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function_02.sol:7:13-52"]
 	contracts -> contract
 	contract -> X [label="function"]
-	contracts -> contract_3
-	contract_3 -> f [label="function"]
+	contracts -> contract_4
+	contract_4 -> f [label="function"]
 	f -> parameters [label="parameters"]
 	f -> returns [label="returns"]
 	f -> return [label="body"]
@@ -25,8 +25,8 @@ strict digraph "tests/contract_testcases/solana/expressions/selector_in_free_fun
 	builtins -> external_function [label="arg #0"]
 	external_function -> variable [label="address"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_13 [label="Debug"]
-	diagnostics -> diagnostic_14 [label="Warning"]
+	diagnostics -> diagnostic_14 [label="Debug"]
 	diagnostics -> diagnostic_15 [label="Warning"]
 	diagnostics -> diagnostic_16 [label="Warning"]
+	diagnostics -> diagnostic_17 [label="Warning"]
 }

+ 5 - 5
tests/contract_testcases/solana/expressions/slice.dot

@@ -3,14 +3,14 @@ strict digraph "tests/contract_testcases/solana/expressions/slice.sol" {
 	foo [label="function foo\ncontract: slice\ntests/contract_testcases/solana/expressions/slice.sol:3:5-35\nsignature foo(bytes)\nvisibility public\nmutability nonpayable"]
 	parameters [label="parameters\nbytes foo"]
 	diagnostic [label="found contract ‘slice’\nlevel Debug\ntests/contract_testcases/solana/expressions/slice.sol:1:1-2:16"]
-	diagnostic_6 [label="declaration of ‘foo’ shadows function\nlevel Warning\ntests/contract_testcases/solana/expressions/slice.sol:3:24-27"]
+	diagnostic_7 [label="declaration of ‘foo’ shadows function\nlevel Warning\ntests/contract_testcases/solana/expressions/slice.sol:3:24-27"]
 	note [label="previous declaration of function\ntests/contract_testcases/solana/expressions/slice.sol:3:14-17"]
-	diagnostic_8 [label="slice not supported yet\nlevel Error\ntests/contract_testcases/solana/expressions/slice.sol:4:20-27"]
+	diagnostic_9 [label="slice not supported yet\nlevel Error\ntests/contract_testcases/solana/expressions/slice.sol:4:20-27"]
 	contracts -> contract
 	contract -> foo [label="function"]
 	foo -> parameters [label="parameters"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Warning"]
-	diagnostic_6 -> note [label="note"]
-	diagnostics -> diagnostic_8 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Warning"]
+	diagnostic_7 -> note [label="note"]
+	diagnostics -> diagnostic_9 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/expressions/tx.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/expressions/tx.sol" {
 	test [label="function test\ncontract: foo\ntests/contract_testcases/solana/expressions/tx.sol:3:13-58\nsignature test()\nvisibility public\nmutability pure"]
 	returns [label="returns\naddress "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/tx.sol:2:9-22"]
-	diagnostic_6 [label="builtin ‘tx.origin’ does not exist\nlevel Error\ntests/contract_testcases/solana/expressions/tx.sol:4:24-26"]
+	diagnostic_7 [label="builtin ‘tx.origin’ does not exist\nlevel Error\ntests/contract_testcases/solana/expressions/tx.sol:4:24-26"]
 	contracts -> contract
 	contract -> test [label="function"]
 	test -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/expressions/tx_01.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/expressions/tx_01.sol" {
 	test [label="function test\ncontract: foo\ntests/contract_testcases/solana/expressions/tx_01.sol:3:13-57\nsignature test()\nvisibility public\nmutability pure"]
 	returns [label="returns\nuint64 "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/expressions/tx_01.sol:2:9-22"]
-	diagnostic_6 [label="builtin ‘tx.gasprice’ does not exist\nlevel Error\ntests/contract_testcases/solana/expressions/tx_01.sol:4:24-26"]
+	diagnostic_7 [label="builtin ‘tx.gasprice’ does not exist\nlevel Error\ntests/contract_testcases/solana/expressions/tx_01.sol:4:24-26"]
 	contracts -> contract
 	contract -> test [label="function"]
 	test -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/hash/constants_hash_tests.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/solana/hash/constants_hash_tests.sol" {
 	contract [label="contract tester\ntests/contract_testcases/solana/hash/constants_hash_tests.sol:2:9-25"]
 	test [label="function test\ncontract: tester\ntests/contract_testcases/solana/hash/constants_hash_tests.sol:3:13-35\nsignature test()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘tester’\nlevel Debug\ntests/contract_testcases/solana/hash/constants_hash_tests.sol:2:9-25"]
-	diagnostic_5 [label="unknown function or type ‘blake2_256’\nlevel Error\ntests/contract_testcases/solana/hash/constants_hash_tests.sol:4:32-42"]
+	diagnostic_6 [label="unknown function or type ‘blake2_256’\nlevel Error\ntests/contract_testcases/solana/hash/constants_hash_tests.sol:4:32-42"]
 	contracts -> contract
 	contract -> test [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/hash/constants_hash_tests_01.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/solana/hash/constants_hash_tests_01.sol
 	contract [label="contract tester\ntests/contract_testcases/solana/hash/constants_hash_tests_01.sol:2:9-25"]
 	test [label="function test\ncontract: tester\ntests/contract_testcases/solana/hash/constants_hash_tests_01.sol:3:13-35\nsignature test()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘tester’\nlevel Debug\ntests/contract_testcases/solana/hash/constants_hash_tests_01.sol:2:9-25"]
-	diagnostic_5 [label="unknown function or type ‘blake2_128’\nlevel Error\ntests/contract_testcases/solana/hash/constants_hash_tests_01.sol:4:32-42"]
+	diagnostic_6 [label="unknown function or type ‘blake2_128’\nlevel Error\ntests/contract_testcases/solana/hash/constants_hash_tests_01.sol:4:32-42"]
 	contracts -> contract
 	contract -> test [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/rational/rational.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/rational/rational.sol" {
 	test [label="function test\ncontract: foo\ntests/contract_testcases/solana/rational/rational.sol:3:13-50\nsignature test()\nvisibility public\nmutability nonpayable"]
 	returns [label="returns\nuint256 "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/rational/rational.sol:2:9-22"]
-	diagnostic_6 [label="conversion to uint256 from rational not allowed\nlevel Error\ntests/contract_testcases/solana/rational/rational.sol:4:26-29"]
+	diagnostic_7 [label="conversion to uint256 from rational not allowed\nlevel Error\ntests/contract_testcases/solana/rational/rational.sol:4:26-29"]
 	contracts -> contract
 	contract -> test [label="function"]
 	test -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }

+ 4 - 4
tests/contract_testcases/solana/returns/return_err.dot

@@ -4,13 +4,13 @@ strict digraph "tests/contract_testcases/solana/returns/return_err.sol" {
 	number_literal [label="uint256 literal: 0\ntests/contract_testcases/solana/returns/return_err.sol:3:32-33"]
 	get [label="function get\ncontract: foo\ntests/contract_testcases/solana/returns/return_err.sol:5:13-34\nsignature get()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/returns/return_err.sol:2:9-22"]
-	diagnostic_7 [label="function has no return values\nlevel Error\ntests/contract_testcases/solana/returns/return_err.sol:6:17-27"]
-	diagnostic_8 [label="storage variable 'val' has been assigned, but never read\nlevel Warning\ntests/contract_testcases/solana/returns/return_err.sol:3:13-33"]
+	diagnostic_8 [label="function has no return values\nlevel Error\ntests/contract_testcases/solana/returns/return_err.sol:6:17-27"]
+	diagnostic_9 [label="storage variable 'val' has been assigned, but never read\nlevel Warning\ntests/contract_testcases/solana/returns/return_err.sol:3:13-33"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
 	contract -> get [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
-	diagnostics -> diagnostic_8 [label="Warning"]
+	diagnostics -> diagnostic_8 [label="Error"]
+	diagnostics -> diagnostic_9 [label="Warning"]
 }

+ 4 - 4
tests/contract_testcases/solana/returns/return_err_01.dot

@@ -5,14 +5,14 @@ strict digraph "tests/contract_testcases/solana/returns/return_err_01.sol" {
 	get [label="function get\ncontract: foo\ntests/contract_testcases/solana/returns/return_err_01.sol:5:13-55\nsignature get()\nvisibility public\nmutability nonpayable"]
 	returns [label="returns\nuint256 \nuint256 "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/returns/return_err_01.sol:2:9-22"]
-	diagnostic_8 [label="incorrect number of return values, expected 2 but got 3\nlevel Error\ntests/contract_testcases/solana/returns/return_err_01.sol:6:17-39"]
-	diagnostic_9 [label="storage variable 'val' has been assigned, but never read\nlevel Warning\ntests/contract_testcases/solana/returns/return_err_01.sol:3:13-33"]
+	diagnostic_9 [label="incorrect number of return values, expected 2 but got 3\nlevel Error\ntests/contract_testcases/solana/returns/return_err_01.sol:6:17-39"]
+	diagnostic_10 [label="storage variable 'val' has been assigned, but never read\nlevel Warning\ntests/contract_testcases/solana/returns/return_err_01.sol:3:13-33"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
 	contract -> get [label="function"]
 	get -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Error"]
-	diagnostics -> diagnostic_9 [label="Warning"]
+	diagnostics -> diagnostic_9 [label="Error"]
+	diagnostics -> diagnostic_10 [label="Warning"]
 }

+ 12 - 12
tests/contract_testcases/solana/returns/return_err_02.dot

@@ -8,14 +8,14 @@ strict digraph "tests/contract_testcases/solana/returns/return_err_02.sol" {
 	list [label="list\ntests/contract_testcases/solana/returns/return_err_02.sol:5:17-39"]
 	storage_load [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_02.sol:5:17-39"]
 	storage_var [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_02.sol:5:25-28"]
-	storage_load_10 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_02.sol:5:17-39"]
-	storage_var_11 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_02.sol:5:30-33"]
-	storage_load_12 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_02.sol:5:17-39"]
-	storage_var_13 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_02.sol:5:35-38"]
+	storage_load_11 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_02.sol:5:17-39"]
+	storage_var_12 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_02.sol:5:30-33"]
+	storage_load_13 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_02.sol:5:17-39"]
+	storage_var_14 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_02.sol:5:35-38"]
 	get [label="function get\ncontract: foo\ntests/contract_testcases/solana/returns/return_err_02.sol:8:13-55\nsignature get()\nvisibility public\nmutability nonpayable"]
-	returns_15 [label="returns\nuint256 \nuint256 "]
+	returns_16 [label="returns\nuint256 \nuint256 "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/returns/return_err_02.sol:2:9-22"]
-	diagnostic_18 [label="incorrect number of return values, expected 2 but got 3\nlevel Error\ntests/contract_testcases/solana/returns/return_err_02.sol:9:17-27"]
+	diagnostic_19 [label="incorrect number of return values, expected 2 but got 3\nlevel Error\ntests/contract_testcases/solana/returns/return_err_02.sol:9:17-27"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
@@ -25,12 +25,12 @@ strict digraph "tests/contract_testcases/solana/returns/return_err_02.sol" {
 	return -> list [label="expr"]
 	list -> storage_load [label="entry #0"]
 	storage_load -> storage_var [label="expr"]
-	list -> storage_load_10 [label="entry #1"]
-	storage_load_10 -> storage_var_11 [label="expr"]
-	list -> storage_load_12 [label="entry #2"]
-	storage_load_12 -> storage_var_13 [label="expr"]
+	list -> storage_load_11 [label="entry #1"]
+	storage_load_11 -> storage_var_12 [label="expr"]
+	list -> storage_load_13 [label="entry #2"]
+	storage_load_13 -> storage_var_14 [label="expr"]
 	contract -> get [label="function"]
-	get -> returns_15 [label="returns"]
+	get -> returns_16 [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_18 [label="Error"]
+	diagnostics -> diagnostic_19 [label="Error"]
 }

+ 10 - 10
tests/contract_testcases/solana/returns/return_err_03.dot

@@ -8,13 +8,13 @@ strict digraph "tests/contract_testcases/solana/returns/return_err_03.sol" {
 	list [label="list\ntests/contract_testcases/solana/returns/return_err_03.sol:5:17-39"]
 	storage_load [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_03.sol:5:17-39"]
 	storage_var [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_03.sol:5:25-28"]
-	storage_load_10 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_03.sol:5:17-39"]
-	storage_var_11 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_03.sol:5:30-33"]
-	storage_load_12 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_03.sol:5:17-39"]
-	storage_var_13 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_03.sol:5:35-38"]
+	storage_load_11 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_03.sol:5:17-39"]
+	storage_var_12 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_03.sol:5:30-33"]
+	storage_load_13 [label="storage load uint256\ntests/contract_testcases/solana/returns/return_err_03.sol:5:17-39"]
+	storage_var_14 [label="storage variable\nfoo.val\nuint256 storage\ntests/contract_testcases/solana/returns/return_err_03.sol:5:35-38"]
 	get [label="function get\ncontract: foo\ntests/contract_testcases/solana/returns/return_err_03.sol:8:13-34\nsignature get()\nvisibility public\nmutability nonpayable"]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/returns/return_err_03.sol:2:9-22"]
-	diagnostic_17 [label="function has no return values\nlevel Error\ntests/contract_testcases/solana/returns/return_err_03.sol:9:17-27"]
+	diagnostic_18 [label="function has no return values\nlevel Error\ntests/contract_testcases/solana/returns/return_err_03.sol:9:17-27"]
 	contracts -> contract
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
@@ -24,11 +24,11 @@ strict digraph "tests/contract_testcases/solana/returns/return_err_03.sol" {
 	return -> list [label="expr"]
 	list -> storage_load [label="entry #0"]
 	storage_load -> storage_var [label="expr"]
-	list -> storage_load_10 [label="entry #1"]
-	storage_load_10 -> storage_var_11 [label="expr"]
-	list -> storage_load_12 [label="entry #2"]
-	storage_load_12 -> storage_var_13 [label="expr"]
+	list -> storage_load_11 [label="entry #1"]
+	storage_load_11 -> storage_var_12 [label="expr"]
+	list -> storage_load_13 [label="entry #2"]
+	storage_load_13 -> storage_var_14 [label="expr"]
 	contract -> get [label="function"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_17 [label="Error"]
+	diagnostics -> diagnostic_18 [label="Error"]
 }

+ 2 - 2
tests/contract_testcases/solana/returns/return_err_04.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/solana/returns/return_err_04.sol" {
 	f [label="function f\ncontract: foo\ntests/contract_testcases/solana/returns/return_err_04.sol:3:13-59\nsignature f()\nvisibility public\nmutability nonpayable"]
 	returns [label="returns\nuint256 \nuint256 \nuint256 "]
 	diagnostic [label="found contract ‘foo’\nlevel Debug\ntests/contract_testcases/solana/returns/return_err_04.sol:2:9-22"]
-	diagnostic_6 [label="incorrect number of return values, expected 3 but got 1\nlevel Error\ntests/contract_testcases/solana/returns/return_err_04.sol:5:17-31"]
+	diagnostic_7 [label="incorrect number of return values, expected 3 but got 1\nlevel Error\ntests/contract_testcases/solana/returns/return_err_04.sol:5:17-31"]
 	contracts -> contract
 	contract -> f [label="function"]
 	f -> returns [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }

+ 16 - 0
tests/contract_testcases/substrate/account_info.dot

@@ -0,0 +1,16 @@
+strict digraph "tests/contract_testcases/substrate/account_info.sol" {
+	contract [label="contract c\ntests/contract_testcases/substrate/account_info.sol:1:1-12"]
+	diagnostic [label="found contract ‘c’\nlevel Debug\ntests/contract_testcases/substrate/account_info.sol:1:1-12"]
+	diagnostic_5 [label="type ‘AccountInfo’ not found\nlevel Error\ntests/contract_testcases/substrate/account_info.sol:2:2-13"]
+	diagnostic_6 [label="type ‘AccountInfo’ not found\nlevel Error\ntests/contract_testcases/substrate/account_info.sol:4:15-26"]
+	diagnostic_7 [label="type ‘AccountInfo’ not found\nlevel Error\ntests/contract_testcases/substrate/account_info.sol:4:44-55"]
+	diagnostic_8 [label="type ‘AccountInfo’ not found\nlevel Error\ntests/contract_testcases/substrate/account_info.sol:5:18-29"]
+	diagnostic_9 [label="type ‘AccountInfo’ not found\nlevel Error\ntests/contract_testcases/substrate/account_info.sol:5:48-59"]
+	contracts -> contract
+	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_8 [label="Error"]
+	diagnostics -> diagnostic_9 [label="Error"]
+}

+ 6 - 0
tests/contract_testcases/substrate/account_info.sol

@@ -0,0 +1,6 @@
+contract c {
+	AccountInfo ai;
+
+	function pub(AccountInfo) public returns (AccountInfo) {}
+	function notpub(AccountInfo) private returns (AccountInfo) {}
+}

+ 1 - 1
tests/contract_testcases/substrate/function_types/decls_07.dot

@@ -1,7 +1,7 @@
 strict digraph "tests/contract_testcases/substrate/function_types/decls_07.sol" {
 	contract [label="contract test\ntests/contract_testcases/substrate/function_types/decls_07.sol:1:1-15"]
 	diagnostic [label="found contract ‘test’\nlevel Debug\ntests/contract_testcases/substrate/function_types/decls_07.sol:1:1-15"]
-	diagnostic_5 [label="return type ‘function internal’ not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/function_types/decls_07.sol:2:44-90"]
+	diagnostic_5 [label="return type ‘function internal’ not allowed in public or external functions\nlevel Error\ntests/contract_testcases/substrate/function_types/decls_07.sol:2:44-90"]
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic_5 [label="Error"]

+ 1 - 1
tests/solana.rs

@@ -259,7 +259,7 @@ fn serialize_parameters(
         // dup_info
         v.write_u8(0xff).unwrap();
         // signer
-        v.write_u8(1).unwrap();
+        v.write_u8(0).unwrap();
         // is_writable
         v.write_u8(1).unwrap();
         // executable

+ 123 - 0
tests/solana_tests/account_info.rs

@@ -0,0 +1,123 @@
+use crate::build_solidity;
+use ethabi::Token;
+
+#[test]
+fn lamports() {
+    let mut vm = build_solidity(
+        r#"
+        contract c {
+            function test() public payable returns (uint64) {
+                for (uint32 i = 0; i < tx.accounts.length; i++) {
+                    AccountInfo ai = tx.accounts[i];
+
+                    assert(ai.is_writable);
+                    assert(!ai.is_signer);
+                    assert(ai.executable);
+
+                    if (ai.key == msg.sender) {
+                        return ai.lamports;
+                    }
+                }
+
+                revert("account not found");
+            }
+        }"#,
+    );
+
+    vm.constructor("c", &[], 0);
+
+    vm.account_data.get_mut(&vm.origin).unwrap().lamports = 17672630920854456917u64;
+
+    let returns = vm.function("test", &[], &[], 0, None);
+
+    assert_eq!(
+        returns[0],
+        Token::Uint(ethereum_types::U256::from(17672630920854456917u64))
+    );
+}
+
+#[test]
+fn owner() {
+    let mut vm = build_solidity(
+        r#"
+        contract c {
+            function test() public payable returns (address) {
+                for (uint32 i = 0; i < tx.accounts.length; i++) {
+                    AccountInfo ai = tx.accounts[i];
+
+                    if (ai.key == address(this)) {
+                        return ai.owner;
+                    }
+                }
+
+                revert("account not found");
+            }
+        }"#,
+    );
+
+    vm.constructor("c", &[], 0);
+
+    let returns = vm.function("test", &[], &[], 0, None);
+
+    let owner = vm.stack[0].program.to_vec();
+
+    assert_eq!(returns[0], Token::FixedBytes(owner));
+}
+
+#[test]
+fn data() {
+    let mut vm = build_solidity(
+        r#"
+        contract c {
+            function test(uint32 index) public payable returns (uint8) {
+                for (uint32 i = 0; i < tx.accounts.length; i++) {
+                    AccountInfo ai = tx.accounts[i];
+
+                    if (ai.key == address(this)) {
+                        return ai.data[index];
+                    }
+                }
+
+                revert("account not found");
+            }
+
+            function test2() public payable returns (uint32) {
+                for (uint32 i = 0; i < tx.accounts.length; i++) {
+                    AccountInfo ai = tx.accounts[i];
+
+                    if (ai.key == address(this)) {
+                        return ai.data.readUint32LE(1);
+                    }
+                }
+
+                revert("account not found");
+            }
+        }"#,
+    );
+
+    vm.constructor("c", &[], 0);
+
+    for i in 0..10 {
+        let returns = vm.function(
+            "test",
+            &[Token::Uint(ethereum_types::U256::from(i))],
+            &[],
+            0,
+            None,
+        );
+
+        let this = &vm.stack[0].data;
+
+        let val = vm.account_data[this].data[i];
+
+        assert_eq!(returns[0], Token::Uint(ethereum_types::U256::from(val)));
+    }
+
+    let returns = vm.function("test2", &[], &[], 0, None);
+
+    let this = &vm.stack[0].data;
+
+    let val = u32::from_le_bytes(vm.account_data[this].data[1..5].try_into().unwrap());
+
+    assert_eq!(returns[0], Token::Uint(ethereum_types::U256::from(val)));
+}

+ 1 - 0
tests/solana_tests/mod.rs

@@ -1,5 +1,6 @@
 mod abi;
 mod accessor;
+mod account_info;
 mod arrays;
 mod balance;
 mod builtin;

Some files were not shown because too many files changed in this diff