瀏覽代碼

Merge pull request #924 from seanyoung/create-program-address

Improve slice support and add `create_program_address()` solana builtin
Sean Young 3 年之前
父節點
當前提交
08ee36e3b4
共有 100 個文件被更改,包括 1420 次插入599 次删除
  1. 4 0
      docs/language/builtins.rst
  2. 48 9
      docs/targets/solana.rst
  3. 9 0
      integration/solana/builtins.sol
  4. 11 0
      integration/solana/builtins.spec.ts
  5. 1 1
      src/abi/substrate.rs
  6. 1 1
      src/bin/languageserver/mod.rs
  7. 23 5
      src/codegen/cfg.rs
  8. 21 16
      src/codegen/expression.rs
  9. 6 3
      src/codegen/external_functions.rs
  10. 2 0
      src/codegen/mod.rs
  11. 3 2
      src/codegen/statements.rs
  12. 1 1
      src/codegen/vector_to_slice.rs
  13. 5 5
      src/codegen/yul/expression.rs
  14. 26 7
      src/codegen/yul/tests/expression.rs
  15. 26 15
      src/emit/binary.rs
  16. 20 11
      src/emit/ethabiencoder.rs
  17. 106 8
      src/emit/mod.rs
  18. 196 23
      src/emit/solana.rs
  19. 11 9
      src/emit/substrate.rs
  20. 26 2
      src/sema/ast.rs
  21. 150 5
      src/sema/builtin.rs
  22. 6 2
      src/sema/dotgraphviz.rs
  23. 79 23
      src/sema/expression.rs
  24. 1 0
      src/sema/mutability.rs
  25. 6 4
      src/sema/namespace.rs
  26. 44 30
      src/sema/types.rs
  27. 7 4
      src/sema/yul/expression.rs
  28. 2 2
      src/sema/yul/tests/expression.rs
  29. 4 4
      tests/codegen_testcases/solidity/slice1.sol
  30. 2 2
      tests/contract_testcases/ewasm/public_internal_function.dot
  31. 2 2
      tests/contract_testcases/solana/comment.dot
  32. 5 5
      tests/contract_testcases/solana/create_contract/base_contract.dot
  33. 10 10
      tests/contract_testcases/solana/create_contract/base_contract_01.dot
  34. 10 10
      tests/contract_testcases/solana/create_contract/base_contract_02.dot
  35. 16 6
      tests/contract_testcases/solana/expressions/selector_in_free_function.dot
  36. 4 4
      tests/contract_testcases/solana/immutable_function.dot
  37. 36 14
      tests/contract_testcases/solana/import_contracts_via_object.dot
  38. 54 36
      tests/contract_testcases/solana/keep_on_resolving.dot
  39. 122 100
      tests/contract_testcases/solana/override.dot
  40. 3 3
      tests/contract_testcases/solana/structs/parse_structs_06.dot
  41. 29 15
      tests/contract_testcases/solana/type_called_error.dot
  42. 12 8
      tests/contract_testcases/solana/type_decl_broken_more.dot
  43. 69 25
      tests/contract_testcases/solana/using_import.dot
  44. 41 21
      tests/contract_testcases/solana/using_list.dot
  45. 21 7
      tests/contract_testcases/solana/using_literal.dot
  46. 6 6
      tests/contract_testcases/substrate/account_info.dot
  47. 2 2
      tests/contract_testcases/substrate/arrays/array_dimensions.dot
  48. 2 2
      tests/contract_testcases/substrate/arrays/array_dimensions_01.dot
  49. 2 2
      tests/contract_testcases/substrate/arrays/array_dimensions_02.dot
  50. 2 2
      tests/contract_testcases/substrate/arrays/array_dimensions_03.dot
  51. 2 2
      tests/contract_testcases/substrate/arrays/array_dimensions_04.dot
  52. 2 2
      tests/contract_testcases/substrate/arrays/data_locations.dot
  53. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_01.dot
  54. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_02.dot
  55. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_03.dot
  56. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_04.dot
  57. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_05.dot
  58. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_06.dot
  59. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_07.dot
  60. 2 2
      tests/contract_testcases/substrate/arrays/data_locations_08.dot
  61. 2 2
      tests/contract_testcases/substrate/calls/payable_functions.dot
  62. 2 2
      tests/contract_testcases/substrate/calls/payable_functions_01.dot
  63. 2 2
      tests/contract_testcases/substrate/calls/payable_functions_02.dot
  64. 2 2
      tests/contract_testcases/substrate/calls/payable_functions_03.dot
  65. 2 2
      tests/contract_testcases/substrate/contracts/contract_name.dot
  66. 3 3
      tests/contract_testcases/substrate/contracts/contract_name_01.dot
  67. 4 4
      tests/contract_testcases/substrate/contracts/contract_name_02.dot
  68. 3 3
      tests/contract_testcases/substrate/contracts/contract_name_03.dot
  69. 2 2
      tests/contract_testcases/substrate/events/event_decl.dot
  70. 5 5
      tests/contract_testcases/substrate/events/event_decl_02.dot
  71. 3 3
      tests/contract_testcases/substrate/events/event_decl_03.dot
  72. 2 2
      tests/contract_testcases/substrate/events/event_decl_04.dot
  73. 2 2
      tests/contract_testcases/substrate/events/event_decl_05.dot
  74. 3 3
      tests/contract_testcases/substrate/events/event_decl_06.dot
  75. 2 2
      tests/contract_testcases/substrate/events/event_decl_07.dot
  76. 2 2
      tests/contract_testcases/substrate/events/event_decl_08.dot
  77. 2 2
      tests/contract_testcases/substrate/events/event_decl_09.dot
  78. 2 2
      tests/contract_testcases/substrate/events/event_decl_10.dot
  79. 2 2
      tests/contract_testcases/substrate/function_types/decls_06.dot
  80. 2 2
      tests/contract_testcases/substrate/function_types/decls_07.dot
  81. 2 2
      tests/contract_testcases/substrate/function_types/decls_08.dot
  82. 4 4
      tests/contract_testcases/substrate/functions/payable.dot
  83. 4 4
      tests/contract_testcases/substrate/functions/payable_01.dot
  84. 4 4
      tests/contract_testcases/substrate/functions/payable_02.dot
  85. 4 4
      tests/contract_testcases/substrate/functions/payable_03.dot
  86. 2 2
      tests/contract_testcases/substrate/functions/return_not_returns.dot
  87. 2 2
      tests/contract_testcases/substrate/functions/stray_semicolon_01.dot
  88. 6 6
      tests/contract_testcases/substrate/inheritance/inherit_types_03.dot
  89. 4 4
      tests/contract_testcases/substrate/inheritance/test_interface.dot
  90. 2 2
      tests/contract_testcases/substrate/inheritance/test_interface_01.dot
  91. 3 3
      tests/contract_testcases/substrate/inheritance/test_interface_02.dot
  92. 2 2
      tests/contract_testcases/substrate/inheritance/test_interface_03.dot
  93. 2 2
      tests/contract_testcases/substrate/inheritance/test_interface_07.dot
  94. 2 2
      tests/contract_testcases/substrate/inheritance/test_interface_08.dot
  95. 3 3
      tests/contract_testcases/substrate/inheritance/test_override.dot
  96. 2 2
      tests/contract_testcases/substrate/inheritance/test_super.dot
  97. 2 2
      tests/contract_testcases/substrate/inheritance/test_virtual.dot
  98. 2 2
      tests/contract_testcases/substrate/libraries/restrictions.dot
  99. 2 2
      tests/contract_testcases/substrate/libraries/restrictions_01.dot
  100. 2 2
      tests/contract_testcases/substrate/libraries/restrictions_02.dot

+ 4 - 0
docs/language/builtins.rst

@@ -143,6 +143,10 @@ AccountInfo[] ``tx.accounts``
         }
         }
     }
     }
 
 
+address ``tx.program_id``
+    The address or account of the currently executing program. Only available on
+    Solana.
+
 ``block`` properties
 ``block`` properties
 ++++++++++++++++++++++
 ++++++++++++++++++++++
 
 

+ 48 - 9
docs/targets/solana.rst

@@ -11,7 +11,7 @@ Solana has the following differences to Ethereum Solidity:
   signatures.
   signatures.
 - Solana has no concept of gas, so there is no gas functions
 - Solana has no concept of gas, so there is no gas functions
 - Solana balance is stored in a ``uint64``, so *address* ``.balance``, ``.transfer()`` and ``.send()``
 - Solana balance is stored in a ``uint64``, so *address* ``.balance``, ``.transfer()`` and ``.send()``
-  all use uint64 rather than `uint256`.
+  all use ``uint64`` rather than ``uint256``.
 
 
 This is how to build your Solidity for Solana:
 This is how to build your Solidity for Solana:
 
 
@@ -82,25 +82,26 @@ The Solidity langauge on Ethereum allows value transfers with an external call
 or constructor, using the ``auction.bid{value: 501}()`` syntax.
 or constructor, using the ``auction.bid{value: 501}()`` syntax.
 Solana Cross Program Invocation (CPI) does not support this. This means that:
 Solana Cross Program Invocation (CPI) does not support this. This means that:
 
 
- - Specifying `value:`` on an external call or constructor is not permitted
- - The `payable` keyword has no effect
- - `msg.value` is not supported
+ - Specifying ``value:`` on an external call or constructor is not permitted
+ - The ``payable`` keyword has no effect
+ - ``msg.value`` is not supported
 
 
 .. note::
 .. note::
 
 
-    Hypothetically, the caller could transfer native balance and then inform the
-    callee about the amount transferred by specifying this in the instruction data.
-    However, it would be trivial to forge such an operation.
+    Hypothetically, this could be implemented like so: the caller could transfer
+    native balance and then inform the callee about the amount transferred by
+    specifying this in the instruction data. However, it would be trivial to
+    forge such an operation.
 
 
 Receive function
 Receive function
 ________________
 ________________
 
 
-In Solidity the `receive()` function, when defined, is called whenever the native
+In Solidity the ``receive()`` function, when defined, is called whenever the native
 balance for an account gets credited, for example through a contract calling
 balance for an account gets credited, for example through a contract calling
 ``account.transfer(value);``. On Solana, there is no method that implement
 ``account.transfer(value);``. On Solana, there is no method that implement
 this. The balance of an account can be credited without any code being executed.
 this. The balance of an account can be credited without any code being executed.
 
 
-`receive()` functions are not permitted on the Solana target.
+``receive()`` functions are not permitted on the Solana target.
 
 
 Builtin Imports
 Builtin Imports
 ________________
 ________________
@@ -178,6 +179,44 @@ bool ``is_writable``
 bool ``is_signer``
 bool ``is_signer``
     Can the callee assume this account signed the transaction
     Can the callee assume this account signed the transaction
 
 
+Builtin create_program_address
+++++++++++++++++++++++++++++++
+
+This function returns the program derived address for a program address and
+the provided seeds. See the Solana documentation on
+`program derived adddresses <https://edge.docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses>`_.
+
+.. code-block:: solidity
+
+    import {create_program_address} from 'solana';
+
+    contract pda {
+        address token = address"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
+
+        function create_pda(bytes seed2) public returns (address) {
+            return create_program_address(["kabang", seed2], token);
+        }
+    }
+
+Builtin try_find_program_address
+++++++++++++++++++++++++++++++++
+
+This function returns the program derived address for a program address and
+the provided seeds, along with a seed bump. See the Solana documentation on
+`program derived adddresses <https://edge.docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses>`_.
+
+.. code-block:: solidity
+
+    import {try_find_program_address} from 'solana';
+
+    contract pda {
+        address token = address"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
+
+        function create_pda(bytes seed2) public returns (address, bytes1) {
+            return try_find_program_address(["kabang", seed2], token);
+        }
+    }
+
 Using spl-token
 Using spl-token
 _______________
 _______________
 
 

+ 9 - 0
integration/solana/builtins.sol

@@ -1,3 +1,4 @@
+import 'solana';
 
 
 contract builtins {
 contract builtins {
 	function hash_ripemd160(bytes bs) public returns (bytes20) {
 	function hash_ripemd160(bytes bs) public returns (bytes20) {
@@ -19,4 +20,12 @@ contract builtins {
 	function mr_slot() public returns (uint64) {
 	function mr_slot() public returns (uint64) {
 		return block.slot;
 		return block.slot;
 	}
 	}
+
+	function pda(bytes seed1, bytes seed2, address addr) public returns (address) {
+		return create_program_address([seed1, seed2], addr);
+	}
+
+	function pda_with_bump(bytes seed1, bytes seed2, address addr) public returns (address, bytes1) {
+		return try_find_program_address([seed1, seed2], addr);
+	}
 }
 }

+ 11 - 0
integration/solana/builtins.spec.ts

@@ -1,5 +1,7 @@
 import expect from 'expect';
 import expect from 'expect';
 import { loadContract } from './setup';
 import { loadContract } from './setup';
+import { publicKeyToHex } from '@solana/solidity';
+import { PublicKey } from '@solana/web3.js';
 
 
 describe('Deploy solang contract and test', function () {
 describe('Deploy solang contract and test', function () {
     this.timeout(500000);
     this.timeout(500000);
@@ -20,6 +22,15 @@ describe('Deploy solang contract and test', function () {
 
 
         expect(res.result).toBe("0x823ad8e1757b879aac338f9a18542928c668e479b37e4a56f024016215c5928c");
         expect(res.result).toBe("0x823ad8e1757b879aac338f9a18542928c668e479b37e4a56f024016215c5928c");
 
 
+        let addrs = new PublicKey("BPFLoaderUpgradeab1e11111111111111111111111");
+        let expected = new PublicKey("BwqrghZA2htAcqq8dzP1WDAhTXYTYWj7CHxF5j7TDBAe");
+        res = await contract.functions.pda('0x', '0x01', publicKeyToHex(addrs));
+        expect(res.result).toBe(publicKeyToHex(expected));
+
+        res = await contract.functions.pda_with_bump('0x', '0x01', publicKeyToHex(addrs));
+        expect(res.result[0]).toBe("0x00c13b4820057d4d07cddf24058df4034cd3379a5f863b4e061ad2c29be62fd5");
+        expect(res.result[1]).toBe("0xfe");
+
         res = await contract.functions.mr_now([]);
         res = await contract.functions.mr_now([]);
 
 
         let now = Math.floor(+new Date() / 1000);
         let now = Math.floor(+new Date() / 1000);

+ 1 - 1
src/abi/substrate.rs

@@ -532,7 +532,7 @@ fn ty_to_abi(ty: &ast::Type, ns: &ast::Namespace, registry: &mut Abi) -> ParamTy
             let mut param_ty = ty_to_abi(ty, ns, registry);
             let mut param_ty = ty_to_abi(ty, ns, registry);
 
 
             for d in dims {
             for d in dims {
-                if let Some(d) = d {
+                if let ast::ArrayLength::Fixed(d) = d {
                     param_ty = ParamType {
                     param_ty = ParamType {
                         ty: registry.builtin_array_type(param_ty.ty, d.to_usize().unwrap()),
                         ty: registry.builtin_array_type(param_ty.ty, d.to_usize().unwrap()),
                         display_name: vec![],
                         display_name: vec![],

+ 1 - 1
src/bin/languageserver/mod.rs

@@ -949,7 +949,7 @@ impl SolangServer {
         }
         }
 
 
         for fnc in &ns.functions {
         for fnc in &ns.functions {
-            if fnc.is_accessor {
+            if fnc.is_accessor || fnc.loc == pt::Loc::Builtin {
                 // accessor functions are synthetic; ignore them, all the locations are fake
                 // accessor functions are synthetic; ignore them, all the locations are fake
                 continue;
                 continue;
             }
             }

+ 23 - 5
src/codegen/cfg.rs

@@ -285,8 +285,9 @@ impl Instr {
 #[derive(Clone, Debug)]
 #[derive(Clone, Debug)]
 #[allow(clippy::large_enum_variant)]
 #[allow(clippy::large_enum_variant)]
 pub enum InternalCallTy {
 pub enum InternalCallTy {
-    Static(usize),
+    Static { cfg_no: usize },
     Dynamic(Expression),
     Dynamic(Expression),
+    Builtin { ast_func_no: usize },
 }
 }
 
 
 #[derive(Clone, PartialEq)]
 #[derive(Clone, PartialEq)]
@@ -904,7 +905,24 @@ impl ControlFlowGraph {
             }
             }
             Instr::Call {
             Instr::Call {
                 res,
                 res,
-                call: InternalCallTy::Static(cfg_no),
+                call: InternalCallTy::Builtin { ast_func_no },
+                args,
+                ..
+            } => format!(
+                "{} = call builtin {} {}",
+                res.iter()
+                    .map(|local| format!("%{}", self.vars[local].id.name))
+                    .collect::<Vec<String>>()
+                    .join(", "),
+                ns.functions[*ast_func_no].name,
+                args.iter()
+                    .map(|expr| self.expr_to_string(contract, ns, expr))
+                    .collect::<Vec<String>>()
+                    .join(", ")
+            ),
+            Instr::Call {
+                res,
+                call: InternalCallTy::Static { cfg_no },
                 args,
                 args,
                 ..
                 ..
             } => format!(
             } => format!(
@@ -1492,7 +1510,7 @@ fn function_cfg(
                     Instr::Call {
                     Instr::Call {
                         res: Vec::new(),
                         res: Vec::new(),
                         return_tys: Vec::new(),
                         return_tys: Vec::new(),
-                        call: InternalCallTy::Static(cfg_no),
+                        call: InternalCallTy::Static { cfg_no },
                         args,
                         args,
                     },
                     },
                 );
                 );
@@ -1504,7 +1522,7 @@ fn function_cfg(
                     Instr::Call {
                     Instr::Call {
                         res: Vec::new(),
                         res: Vec::new(),
                         return_tys: Vec::new(),
                         return_tys: Vec::new(),
-                        call: InternalCallTy::Static(cfg_no),
+                        call: InternalCallTy::Static { cfg_no },
                         args: Vec::new(),
                         args: Vec::new(),
                     },
                     },
                 );
                 );
@@ -1695,7 +1713,7 @@ pub fn generate_modifier_dispatch(
     // create the instruction for the place holder
     // create the instruction for the place holder
     let placeholder = Instr::Call {
     let placeholder = Instr::Call {
         res: func.symtable.returns.clone(),
         res: func.symtable.returns.clone(),
-        call: InternalCallTy::Static(cfg_no),
+        call: InternalCallTy::Static { cfg_no },
         return_tys,
         return_tys,
         args: func
         args: func
             .params
             .params

+ 21 - 16
src/codegen/expression.rs

@@ -11,7 +11,10 @@ use crate::codegen::unused_variable::should_remove_assignment;
 use crate::codegen::{Builtin, Expression};
 use crate::codegen::{Builtin, Expression};
 use crate::sema::{
 use crate::sema::{
     ast,
     ast,
-    ast::{CallTy, FormatArg, Function, Namespace, Parameter, RetrieveType, StringLocation, Type},
+    ast::{
+        ArrayLength, CallTy, FormatArg, Function, Namespace, Parameter, RetrieveType,
+        StringLocation, Type,
+    },
     diagnostics::Diagnostics,
     diagnostics::Diagnostics,
     eval::{eval_const_number, eval_const_rational},
     eval::{eval_const_number, eval_const_rational},
     expression::{bigint_to_expression, ResolveTo},
     expression::{bigint_to_expression, ResolveTo},
@@ -374,7 +377,7 @@ pub fn expression(
                     elem_ty: elem_ty.clone(),
                     elem_ty: elem_ty.clone(),
                 },
                 },
                 Type::Array(_, dim) => match dim.last().unwrap() {
                 Type::Array(_, dim) => match dim.last().unwrap() {
-                    None => {
+                    ArrayLength::Dynamic => {
                         if ns.target == Target::Solana {
                         if ns.target == Target::Solana {
                             Expression::StorageArrayLength {
                             Expression::StorageArrayLength {
                                 loc: *loc,
                                 loc: *loc,
@@ -386,7 +389,7 @@ pub fn expression(
                             load_storage(loc, &ns.storage_type(), array, cfg, vartab)
                             load_storage(loc, &ns.storage_type(), array, cfg, vartab)
                         }
                         }
                     }
                     }
-                    Some(length) => {
+                    ArrayLength::Fixed(length) => {
                         let ast_expr = bigint_to_expression(
                         let ast_expr = bigint_to_expression(
                             loc,
                             loc,
                             length,
                             length,
@@ -397,6 +400,7 @@ pub fn expression(
                         .unwrap();
                         .unwrap();
                         expression(&ast_expr, cfg, contract_no, func, ns, vartab, opt)
                         expression(&ast_expr, cfg, contract_no, func, ns, vartab, opt)
                     }
                     }
+                    _ => unreachable!(),
                 },
                 },
                 _ => unreachable!(),
                 _ => unreachable!(),
             }
             }
@@ -2008,14 +2012,22 @@ pub fn emit_function_call(
                     .collect();
                     .collect();
 
 
                 let function_no = if let Some(signature) = signature {
                 let function_no = if let Some(signature) = signature {
-                    &ns.contracts[callee_contract_no].virtual_functions[signature]
+                    ns.contracts[callee_contract_no].virtual_functions[signature]
                 } else {
                 } else {
-                    function_no
+                    *function_no
                 };
                 };
 
 
-                let cfg_no = ns.contracts[callee_contract_no].all_functions[function_no];
+                let ftype = &ns.functions[function_no];
 
 
-                let ftype = &ns.functions[*function_no];
+                let call = if ns.functions[function_no].loc == pt::Loc::Builtin {
+                    InternalCallTy::Builtin {
+                        ast_func_no: function_no,
+                    }
+                } else {
+                    InternalCallTy::Static {
+                        cfg_no: ns.contracts[callee_contract_no].all_functions[&function_no],
+                    }
+                };
 
 
                 if !ftype.returns.is_empty() {
                 if !ftype.returns.is_empty() {
                     let mut res = Vec::new();
                     let mut res = Vec::new();
@@ -2038,7 +2050,7 @@ pub fn emit_function_call(
                         vartab,
                         vartab,
                         Instr::Call {
                         Instr::Call {
                             res,
                             res,
-                            call: InternalCallTy::Static(cfg_no),
+                            call,
                             args,
                             args,
                             return_tys,
                             return_tys,
                         },
                         },
@@ -2051,7 +2063,7 @@ pub fn emit_function_call(
                         Instr::Call {
                         Instr::Call {
                             res: Vec::new(),
                             res: Vec::new(),
                             return_tys: Vec::new(),
                             return_tys: Vec::new(),
-                            call: InternalCallTy::Static(cfg_no),
+                            call,
                             args,
                             args,
                         },
                         },
                     );
                     );
@@ -2806,13 +2818,6 @@ fn array_subscript(
                     )),
                     )),
                 )
                 )
             }
             }
-            Type::Array(_, dim) if dim.last().unwrap().is_some() => Expression::Subscript(
-                *loc,
-                elem_ty.clone(),
-                array_ty.clone(),
-                Box::new(array),
-                Box::new(Expression::Variable(index_loc, coerced_ty, pos)),
-            ),
             Type::DynamicBytes | Type::Array(..) => Expression::Subscript(
             Type::DynamicBytes | Type::Array(..) => Expression::Subscript(
                 *loc,
                 *loc,
                 elem_ty.clone(),
                 elem_ty.clone(),

+ 6 - 3
src/codegen/external_functions.rs

@@ -1,6 +1,7 @@
 use crate::sema::ast::{DestructureField, Expression, Namespace, Statement};
 use crate::sema::ast::{DestructureField, Expression, Namespace, Statement};
 use crate::sema::Recurse;
 use crate::sema::Recurse;
 use indexmap::IndexSet;
 use indexmap::IndexSet;
+use solang_parser::pt;
 
 
 #[derive(Default)]
 #[derive(Default)]
 struct CallList {
 struct CallList {
@@ -42,9 +43,11 @@ pub fn add_external_functions(contract_no: usize, ns: &mut Namespace) {
 
 
         // add functions to contract functions list
         // add functions to contract functions list
         for function_no in &call_list.solidity {
         for function_no in &call_list.solidity {
-            ns.contracts[contract_no]
-                .all_functions
-                .insert(*function_no, usize::MAX);
+            if ns.functions[*function_no].loc != pt::Loc::Builtin {
+                ns.contracts[contract_no]
+                    .all_functions
+                    .insert(*function_no, usize::MAX);
+            }
         }
         }
 
 
         for yul_function_no in &call_list.yul {
         for yul_function_no in &call_list.yul {

+ 2 - 0
src/codegen/mod.rs

@@ -1214,6 +1214,7 @@ pub enum Builtin {
     Ripemd160,
     Ripemd160,
     Sender,
     Sender,
     Slot,
     Slot,
+    ProgramId,
     Sha256,
     Sha256,
     Signature,
     Signature,
     SignatureVerify,
     SignatureVerify,
@@ -1274,6 +1275,7 @@ impl From<&ast::Builtin> for Builtin {
             ast::Builtin::Ripemd160 => Builtin::Ripemd160,
             ast::Builtin::Ripemd160 => Builtin::Ripemd160,
             ast::Builtin::Sender => Builtin::Sender,
             ast::Builtin::Sender => Builtin::Sender,
             ast::Builtin::Slot => Builtin::Slot,
             ast::Builtin::Slot => Builtin::Slot,
+            ast::Builtin::ProgramId => Builtin::ProgramId,
             ast::Builtin::Sha256 => Builtin::Sha256,
             ast::Builtin::Sha256 => Builtin::Sha256,
             ast::Builtin::Signature => Builtin::Signature,
             ast::Builtin::Signature => Builtin::Signature,
             ast::Builtin::SignatureVerify => Builtin::SignatureVerify,
             ast::Builtin::SignatureVerify => Builtin::SignatureVerify,

+ 3 - 2
src/codegen/statements.rs

@@ -15,7 +15,8 @@ use crate::codegen::yul::inline_assembly_cfg;
 use crate::codegen::{Builtin, Expression};
 use crate::codegen::{Builtin, Expression};
 use crate::sema::ast::RetrieveType;
 use crate::sema::ast::RetrieveType;
 use crate::sema::ast::{
 use crate::sema::ast::{
-    CallTy, DestructureField, Function, Namespace, Parameter, Statement, TryCatch, Type,
+    ArrayLength, CallTy, DestructureField, Function, Namespace, Parameter, Statement, TryCatch,
+    Type,
 };
 };
 use crate::sema::Recurse;
 use crate::sema::Recurse;
 use num_traits::Zero;
 use num_traits::Zero;
@@ -1495,7 +1496,7 @@ impl Type {
             Type::Array(ty, dims) => {
             Type::Array(ty, dims) => {
                 ty.default(ns)?;
                 ty.default(ns)?;
 
 
-                if dims.last().unwrap().is_none() {
+                if dims.last() == Some(&ArrayLength::Dynamic) {
                     Some(Expression::AllocDynamicArray(
                     Some(Expression::AllocDynamicArray(
                         pt::Loc::Codegen,
                         pt::Loc::Codegen,
                         self.clone(),
                         self.clone(),

+ 1 - 1
src/codegen/vector_to_slice.rs

@@ -214,7 +214,7 @@ fn update_vectors_to_slice(
                 res,
                 res,
                 expr: Expression::AllocDynamicArray(
                 expr: Expression::AllocDynamicArray(
                     *loc,
                     *loc,
-                    Type::Slice,
+                    Type::Slice(Box::new(Type::Bytes(1))),
                     len.clone(),
                     len.clone(),
                     Some(bs.clone()),
                     Some(bs.clone()),
                 ),
                 ),

+ 5 - 5
src/codegen/yul/expression.rs

@@ -1,4 +1,4 @@
-use crate::ast::{Namespace, Type};
+use crate::ast::{ArrayLength, Namespace, Type};
 use crate::codegen;
 use crate::codegen;
 use crate::codegen::cfg::{ControlFlowGraph, Instr, InternalCallTy};
 use crate::codegen::cfg::{ControlFlowGraph, Instr, InternalCallTy};
 use crate::codegen::vartable::Vartable;
 use crate::codegen::vartable::Vartable;
@@ -138,7 +138,7 @@ fn process_suffix_access(
                 Some(StorageLocation::Calldata(_)),
                 Some(StorageLocation::Calldata(_)),
                 var_no,
                 var_no,
             ) => {
             ) => {
-                if dims.last().unwrap().is_none() {
+                if dims.last() == Some(&ArrayLength::Dynamic) {
                     return Expression::Cast(
                     return Expression::Cast(
                         *loc,
                         *loc,
                         Type::Uint(256),
                         Type::Uint(256),
@@ -158,7 +158,7 @@ fn process_suffix_access(
                 _,
                 _,
             ) = expr
             ) = expr
             {
             {
-                if dims.last().unwrap().is_none() {
+                if dims.last() == Some(&ArrayLength::Dynamic) {
                     return Expression::Builtin(
                     return Expression::Builtin(
                         *loc,
                         *loc,
                         vec![Type::Uint(32)],
                         vec![Type::Uint(32)],
@@ -224,7 +224,7 @@ pub(crate) fn process_function_call(
             Instr::Call {
             Instr::Call {
                 res: Vec::new(),
                 res: Vec::new(),
                 return_tys: Vec::new(),
                 return_tys: Vec::new(),
-                call: InternalCallTy::Static(cfg_no),
+                call: InternalCallTy::Static { cfg_no },
                 args: codegen_args,
                 args: codegen_args,
             },
             },
         );
         );
@@ -252,7 +252,7 @@ pub(crate) fn process_function_call(
         vartab,
         vartab,
         Instr::Call {
         Instr::Call {
             res,
             res,
-            call: InternalCallTy::Static(cfg_no),
+            call: InternalCallTy::Static { cfg_no },
             args: codegen_args,
             args: codegen_args,
             return_tys,
             return_tys,
         },
         },

+ 26 - 7
src/codegen/yul/tests/expression.rs

@@ -5,6 +5,7 @@ use crate::codegen::cfg::ControlFlowGraph;
 use crate::codegen::vartable::Vartable;
 use crate::codegen::vartable::Vartable;
 use crate::codegen::yul::expression::expression;
 use crate::codegen::yul::expression::expression;
 use crate::codegen::{Builtin, Expression, Options};
 use crate::codegen::{Builtin, Expression, Options};
+use crate::sema::ast::ArrayLength;
 use crate::sema::yul::ast;
 use crate::sema::yul::ast;
 use crate::sema::yul::ast::YulSuffix;
 use crate::sema::yul::ast::YulSuffix;
 use crate::{sema, Target};
 use crate::{sema, Target};
@@ -355,7 +356,7 @@ fn offset_suffix() {
         loc,
         loc,
         Box::new(ast::YulExpression::SolidityLocalVariable(
         Box::new(ast::YulExpression::SolidityLocalVariable(
             loc,
             loc,
-            Type::Array(Box::new(Type::Uint(256)), vec![None]),
+            Type::Array(Box::new(Type::Uint(256)), vec![ArrayLength::Dynamic]),
             Some(StorageLocation::Calldata(loc)),
             Some(StorageLocation::Calldata(loc)),
             1,
             1,
         )),
         )),
@@ -369,7 +370,7 @@ fn offset_suffix() {
             Type::Uint(256),
             Type::Uint(256),
             Box::new(Expression::Variable(
             Box::new(Expression::Variable(
                 loc,
                 loc,
-                Type::Array(Box::new(Type::Uint(256)), vec![None]),
+                Type::Array(Box::new(Type::Uint(256)), vec![ArrayLength::Dynamic]),
                 1
                 1
             ))
             ))
         )
         )
@@ -389,7 +390,10 @@ fn offset_suffix_panic_calldata() {
         loc,
         loc,
         Box::new(ast::YulExpression::SolidityLocalVariable(
         Box::new(ast::YulExpression::SolidityLocalVariable(
             loc,
             loc,
-            Type::Array(Box::new(Type::Uint(32)), vec![None, Some(BigInt::from(3))]),
+            Type::Array(
+                Box::new(Type::Uint(32)),
+                vec![ArrayLength::Dynamic, ArrayLength::Fixed(BigInt::from(3))],
+            ),
             Some(StorageLocation::Calldata(loc)),
             Some(StorageLocation::Calldata(loc)),
             3,
             3,
         )),
         )),
@@ -431,7 +435,11 @@ fn length_suffix() {
             loc,
             loc,
             Type::Array(
             Type::Array(
                 Box::new(Type::Uint(32)),
                 Box::new(Type::Uint(32)),
-                vec![None, Some(BigInt::from(3)), None],
+                vec![
+                    ArrayLength::Dynamic,
+                    ArrayLength::Fixed(BigInt::from(3)),
+                    ArrayLength::Dynamic,
+                ],
             ),
             ),
             Some(StorageLocation::Calldata(loc)),
             Some(StorageLocation::Calldata(loc)),
             3,
             3,
@@ -450,7 +458,11 @@ fn length_suffix() {
                 loc,
                 loc,
                 Type::Array(
                 Type::Array(
                     Box::new(Type::Uint(32)),
                     Box::new(Type::Uint(32)),
-                    vec![None, Some(BigInt::from(3)), None]
+                    vec![
+                        ArrayLength::Dynamic,
+                        ArrayLength::Fixed(BigInt::from(3)),
+                        ArrayLength::Dynamic
+                    ]
                 ),
                 ),
                 3
                 3
             )]
             )]
@@ -471,7 +483,10 @@ fn length_suffix_panic() {
         loc,
         loc,
         Box::new(ast::YulExpression::SolidityLocalVariable(
         Box::new(ast::YulExpression::SolidityLocalVariable(
             loc,
             loc,
-            Type::Array(Box::new(Type::Uint(32)), vec![None, Some(BigInt::from(3))]),
+            Type::Array(
+                Box::new(Type::Uint(32)),
+                vec![ArrayLength::Dynamic, ArrayLength::Fixed(BigInt::from(3))],
+            ),
             Some(StorageLocation::Calldata(loc)),
             Some(StorageLocation::Calldata(loc)),
             3,
             3,
         )),
         )),
@@ -489,7 +504,11 @@ fn length_suffix_panic() {
                 loc,
                 loc,
                 Type::Array(
                 Type::Array(
                     Box::new(Type::Uint(32)),
                     Box::new(Type::Uint(32)),
-                    vec![None, Some(BigInt::from(3)), None]
+                    vec![
+                        ArrayLength::Dynamic,
+                        ArrayLength::Fixed(BigInt::from(3)),
+                        ArrayLength::Dynamic
+                    ]
                 ),
                 ),
                 3
                 3
             )]
             )]

+ 26 - 15
src/emit/binary.rs

@@ -1,4 +1,4 @@
-use crate::sema::ast::{BuiltinStruct, Contract, Namespace, Type};
+use crate::sema::ast::{ArrayLength, BuiltinStruct, Contract, Namespace, Type};
 use std::cell::RefCell;
 use std::cell::RefCell;
 use std::ffi::CStr;
 use std::ffi::CStr;
 use std::path::Path;
 use std::path::Path;
@@ -762,7 +762,7 @@ impl<'a> Binary<'a> {
     pub(crate) fn llvm_field_ty(&self, ty: &Type, ns: &Namespace) -> BasicTypeEnum<'a> {
     pub(crate) fn llvm_field_ty(&self, ty: &Type, ns: &Namespace) -> BasicTypeEnum<'a> {
         let llvm_ty = self.llvm_type(ty, ns);
         let llvm_ty = self.llvm_type(ty, ns);
         match ty.deref_memory() {
         match ty.deref_memory() {
-            Type::Array(_, dim) if dim.last().unwrap().is_none() => {
+            Type::Array(_, dim) if dim.last() == Some(&ArrayLength::Dynamic) => {
                 llvm_ty.ptr_type(AddressSpace::Generic).as_basic_type_enum()
                 llvm_ty.ptr_type(AddressSpace::Generic).as_basic_type_enum()
             }
             }
             Type::DynamicBytes | Type::String => {
             Type::DynamicBytes | Type::String => {
@@ -806,18 +806,24 @@ impl<'a> Binary<'a> {
                     let mut dims = dims.iter();
                     let mut dims = dims.iter();
 
 
                     let mut aty = match dims.next().unwrap() {
                     let mut aty = match dims.next().unwrap() {
-                        Some(d) => ty.array_type(d.to_u32().unwrap()),
-                        None => {
+                        ArrayLength::Fixed(d) => ty.array_type(d.to_u32().unwrap()),
+                        ArrayLength::Dynamic => {
                             return self.module.get_struct_type("struct.vector").unwrap().into()
                             return self.module.get_struct_type("struct.vector").unwrap().into()
                         }
                         }
+                        ArrayLength::AnyFixed => {
+                            unreachable!()
+                        }
                     };
                     };
 
 
                     for dim in dims {
                     for dim in dims {
                         match dim {
                         match dim {
-                            Some(d) => aty = aty.array_type(d.to_u32().unwrap()),
-                            None => {
+                            ArrayLength::Fixed(d) => aty = aty.array_type(d.to_u32().unwrap()),
+                            ArrayLength::Dynamic => {
                                 return self.module.get_struct_type("struct.vector").unwrap().into()
                                 return self.module.get_struct_type("struct.vector").unwrap().into()
                             }
                             }
+                            ArrayLength::AnyFixed => {
+                                unreachable!()
+                            }
                         }
                         }
                     }
                     }
 
 
@@ -857,14 +863,15 @@ impl<'a> Binary<'a> {
                             .ptr_type(AddressSpace::Generic),
                             .ptr_type(AddressSpace::Generic),
                     )
                     )
                 }
                 }
-                Type::Slice => BasicTypeEnum::StructType(
+                Type::Slice(ty) => BasicTypeEnum::StructType(
                     self.context.struct_type(
                     self.context.struct_type(
                         &[
                         &[
-                            self.context
-                                .i8_type()
+                            self.llvm_type(ty, ns)
                                 .ptr_type(AddressSpace::Generic)
                                 .ptr_type(AddressSpace::Generic)
                                 .into(),
                                 .into(),
-                            self.context.i32_type().into(),
+                            self.context
+                                .custom_width_int_type(ns.target.ptr_size().into())
+                                .into(),
                         ],
                         ],
                         false,
                         false,
                     ),
                     ),
@@ -946,10 +953,14 @@ impl<'a> Binary<'a> {
             // slice
             // slice
             let slice = vector.into_struct_value();
             let slice = vector.into_struct_value();
 
 
-            self.builder
-                .build_extract_value(slice, 1, "slice_len")
-                .unwrap()
-                .into_int_value()
+            self.builder.build_int_truncate(
+                self.builder
+                    .build_extract_value(slice, 1, "slice_len")
+                    .unwrap()
+                    .into_int_value(),
+                self.context.i32_type(),
+                "len",
+            )
         } else {
         } else {
             let struct_ty = vector
             let struct_ty = vector
                 .into_pointer_value()
                 .into_pointer_value()
@@ -1055,7 +1066,7 @@ impl<'a> Binary<'a> {
     ) -> PointerValue<'a> {
     ) -> PointerValue<'a> {
         match array_ty {
         match array_ty {
             Type::Array(_, dim) => {
             Type::Array(_, dim) => {
-                if dim.last().unwrap().is_some() {
+                if matches!(dim.last(), Some(ArrayLength::Fixed(_))) {
                     // fixed size array
                     // fixed size array
                     unsafe {
                     unsafe {
                         self.builder.build_gep(
                         self.builder.build_gep(

+ 20 - 11
src/emit/ethabiencoder.rs

@@ -194,11 +194,12 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let sum = binary.context.i32_type().const_zero();
                 let sum = binary.context.i32_type().const_zero();
 
 
                 let len = match dims.last().unwrap() {
                 let len = match dims.last().unwrap() {
-                    None => binary.vector_len(arg),
-                    Some(d) => binary
+                    ast::ArrayLength::Dynamic => binary.vector_len(arg),
+                    ast::ArrayLength::Fixed(d) => binary
                         .context
                         .context
                         .i32_type()
                         .i32_type()
                         .const_int(d.to_u64().unwrap(), false),
                         .const_int(d.to_u64().unwrap(), false),
+                    _ => unreachable!(),
                 };
                 };
 
 
                 let normal_array = binary.context.append_basic_block(function, "normal_array");
                 let normal_array = binary.context.append_basic_block(function, "normal_array");
@@ -286,11 +287,12 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 };
                 };
 
 
                 let len = match dims.last().unwrap() {
                 let len = match dims.last().unwrap() {
-                    None => binary.vector_len(arg),
-                    Some(d) => binary
+                    ast::ArrayLength::Dynamic => binary.vector_len(arg),
+                    ast::ArrayLength::Fixed(d) => binary
                         .context
                         .context
                         .i32_type()
                         .i32_type()
                         .const_int(d.to_u64().unwrap(), false),
                         .const_int(d.to_u64().unwrap(), false),
+                    _ => unreachable!(),
                 };
                 };
 
 
                 // plus fixed size elements
                 // plus fixed size elements
@@ -449,7 +451,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let mut sum = binary.context.i32_type().const_zero();
                 let mut sum = binary.context.i32_type().const_zero();
 
 
                 let len = match dims.last().unwrap() {
                 let len = match dims.last().unwrap() {
-                    None => {
+                    ast::ArrayLength::Dynamic => {
                         let array_len = binary.vector_len(arg);
                         let array_len = binary.vector_len(arg);
 
 
                         // A dynamic array will store its own length
                         // A dynamic array will store its own length
@@ -461,10 +463,11 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
 
                         array_len
                         array_len
                     }
                     }
-                    Some(d) => binary
+                    ast::ArrayLength::Fixed(d) => binary
                         .context
                         .context
                         .i32_type()
                         .i32_type()
                         .const_int(d.to_u64().unwrap(), false),
                         .const_int(d.to_u64().unwrap(), false),
+                    _ => unreachable!(),
                 };
                 };
 
 
                 // plus fixed size elements
                 // plus fixed size elements
@@ -614,7 +617,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 // The array must be fixed, dynamic arrays are handled above
                 // The array must be fixed, dynamic arrays are handled above
                 let product: u64 = dims
                 let product: u64 = dims
                     .iter()
                     .iter()
-                    .map(|d| d.as_ref().unwrap().to_u64().unwrap())
+                    .map(|d| d.array_length().unwrap().to_u64().unwrap())
                     .product();
                     .product();
 
 
                 product * EncoderBuilder::encoded_fixed_length(ty, ns)
                 product * EncoderBuilder::encoded_fixed_length(ty, ns)
@@ -770,7 +773,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     )
                     )
                 };
                 };
 
 
-                let array_length = if let Some(d) = &dim.last().unwrap() {
+                let array_length = if let Some(ast::ArrayLength::Fixed(d)) = dim.last() {
                     // fixed length
                     // fixed length
                     binary
                     binary
                         .context
                         .context
@@ -991,7 +994,13 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     arg
                     arg
                 };
                 };
 
 
-                let dim = dim.last().unwrap().as_ref().unwrap().to_u64().unwrap();
+                let dim = dim
+                    .last()
+                    .unwrap()
+                    .array_length()
+                    .unwrap()
+                    .to_u64()
+                    .unwrap();
 
 
                 let normal_array = binary.context.append_basic_block(function, "normal_array");
                 let normal_array = binary.context.append_basic_block(function, "normal_array");
                 let null_array = binary.context.append_basic_block(function, "null_array");
                 let null_array = binary.context.append_basic_block(function, "null_array");
@@ -1772,7 +1781,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     arg
                     arg
                 };
                 };
 
 
-                let array_length = if let Some(d) = &dim.last().unwrap() {
+                let array_length = if let Some(ast::ArrayLength::Fixed(d)) = dim.last() {
                     // fixed length
                     // fixed length
                     binary
                     binary
                         .context
                         .context
@@ -2688,7 +2697,7 @@ impl EthAbiDecoder {
 
 
                 let dest;
                 let dest;
 
 
-                if let Some(d) = &dim.last().unwrap() {
+                if let Some(ast::ArrayLength::Fixed(d)) = dim.last() {
                     dest = to.unwrap_or_else(|| {
                     dest = to.unwrap_or_else(|| {
                         let new = binary
                         let new = binary
                             .builder
                             .builder

+ 106 - 8
src/emit/mod.rs

@@ -1,7 +1,8 @@
 use crate::codegen::{Builtin, Expression};
 use crate::codegen::{Builtin, Expression};
 use crate::sema::ast::RetrieveType;
 use crate::sema::ast::RetrieveType;
 use crate::sema::ast::{
 use crate::sema::ast::{
-    BuiltinStruct, CallTy, Contract, FormatArg, Namespace, Parameter, StringLocation, Type,
+    ArrayLength, BuiltinStruct, CallTy, Contract, FormatArg, Function, Namespace, Parameter,
+    StringLocation, Type,
 };
 };
 use solang_parser::pt;
 use solang_parser::pt;
 use std::convert::TryFrom;
 use std::convert::TryFrom;
@@ -235,6 +236,16 @@ pub trait TargetRuntime<'a> {
     /// Return failure without any result
     /// Return failure without any result
     fn assert_failure<'b>(&self, bin: &'b Binary, data: PointerValue, length: IntValue);
     fn assert_failure<'b>(&self, bin: &'b Binary, data: PointerValue, length: IntValue);
 
 
+    fn builtin_function(
+        &self,
+        _binary: &Binary<'a>,
+        _func: &Function,
+        _args: &[BasicMetadataValueEnum<'a>],
+        _ns: &Namespace,
+    ) -> BasicValueEnum<'a> {
+        unimplemented!();
+    }
+
     /// Calls constructor
     /// Calls constructor
     fn create_contract<'b>(
     fn create_contract<'b>(
         &mut self,
         &mut self,
@@ -407,7 +418,7 @@ pub trait TargetRuntime<'a> {
         match ty {
         match ty {
             Type::Ref(ty) => self.storage_load_slot(bin, ty, slot, slot_ptr, function, ns),
             Type::Ref(ty) => self.storage_load_slot(bin, ty, slot, slot_ptr, function, ns),
             Type::Array(elem_ty, dim) => {
             Type::Array(elem_ty, dim) => {
-                if let Some(d) = &dim.last().unwrap() {
+                if let Some(ArrayLength::Fixed(d)) = dim.last() {
                     let llvm_ty = bin.llvm_type(ty.deref_any(), ns);
                     let llvm_ty = bin.llvm_type(ty.deref_any(), ns);
                     // LLVMSizeOf() produces an i64
                     // LLVMSizeOf() produces an i64
                     let size = bin.builder.build_int_truncate(
                     let size = bin.builder.build_int_truncate(
@@ -699,7 +710,7 @@ pub trait TargetRuntime<'a> {
     ) {
     ) {
         match ty.deref_any() {
         match ty.deref_any() {
             Type::Array(elem_ty, dim) => {
             Type::Array(elem_ty, dim) => {
-                if let Some(d) = &dim.last().unwrap() {
+                if let Some(ArrayLength::Fixed(d)) = dim.last() {
                     bin.emit_static_loop_with_int(
                     bin.emit_static_loop_with_int(
                         function,
                         function,
                         bin.context.i64_type().const_zero(),
                         bin.context.i64_type().const_zero(),
@@ -1010,7 +1021,7 @@ pub trait TargetRuntime<'a> {
             Type::Array(_, dim) => {
             Type::Array(_, dim) => {
                 let ty = ty.array_deref();
                 let ty = ty.array_deref();
 
 
-                if let Some(d) = &dim.last().unwrap() {
+                if let Some(ArrayLength::Fixed(d)) = dim.last() {
                     bin.emit_static_loop_with_int(
                     bin.emit_static_loop_with_int(
                         function,
                         function,
                         bin.context.i64_type().const_zero(),
                         bin.context.i64_type().const_zero(),
@@ -2466,7 +2477,7 @@ pub trait TargetRuntime<'a> {
                 array.into()
                 array.into()
             }
             }
             Expression::AllocDynamicArray(_, ty, size, init) => {
             Expression::AllocDynamicArray(_, ty, size, init) => {
-                if *ty == Type::Slice {
+                if matches!(ty, Type::Slice(_)) {
                     let init = init.as_ref().unwrap();
                     let init = init.as_ref().unwrap();
 
 
                     let data = bin.emit_global_string("const_string", init, true);
                     let data = bin.emit_global_string("const_string", init, true);
@@ -2476,14 +2487,14 @@ pub trait TargetRuntime<'a> {
                         .const_named_struct(&[
                         .const_named_struct(&[
                             data.into(),
                             data.into(),
                             bin.context
                             bin.context
-                                .i32_type()
+                                .custom_width_int_type(ns.target.ptr_size().into())
                                 .const_int(init.len() as u64, false)
                                 .const_int(init.len() as u64, false)
                                 .into(),
                                 .into(),
                         ])
                         ])
                         .into()
                         .into()
                 } else {
                 } else {
                     let elem = match ty {
                     let elem = match ty {
-                        Type::Slice | Type::String | Type::DynamicBytes => Type::Bytes(1),
+                        Type::Slice(_) | Type::String | Type::DynamicBytes => Type::Bytes(1),
                         _ => ty.array_elem(),
                         _ => ty.array_elem(),
                     };
                     };
 
 
@@ -3237,6 +3248,24 @@ pub trait TargetRuntime<'a> {
                     "ptr_to_int",
                     "ptr_to_int",
                 )
                 )
                 .into()
                 .into()
+        } else if matches!((from, to), (Type::DynamicBytes, Type::Slice(_))) {
+            let slice = bin.build_alloca(function, bin.llvm_type(to, ns), "slice");
+
+            let data = bin.vector_bytes(val);
+
+            let data_ptr = bin.builder.build_struct_gep(slice, 0, "data").unwrap();
+
+            bin.builder.build_store(data_ptr, data);
+
+            let len =
+                bin.builder
+                    .build_int_z_extend(bin.vector_len(val), bin.context.i64_type(), "len");
+
+            let len_ptr = bin.builder.build_struct_gep(slice, 1, "len").unwrap();
+
+            bin.builder.build_store(len_ptr, len);
+
+            bin.builder.build_load(slice, "slice")
         } else {
         } else {
             val
             val
         }
         }
@@ -3854,7 +3883,7 @@ pub trait TargetRuntime<'a> {
                     }
                     }
                     Instr::Call {
                     Instr::Call {
                         res,
                         res,
-                        call: InternalCallTy::Static(cfg_no),
+                        call: InternalCallTy::Static { cfg_no },
                         args,
                         args,
                         ..
                         ..
                     } => {
                     } => {
@@ -3930,6 +3959,75 @@ pub trait TargetRuntime<'a> {
                             }
                             }
                         }
                         }
                     }
                     }
+                    Instr::Call {
+                        res,
+                        call: InternalCallTy::Builtin { ast_func_no },
+                        args,
+                        ..
+                    } => {
+                        let mut parms = args
+                            .iter()
+                            .map(|p| self.expression(bin, p, &w.vars, function, ns).into())
+                            .collect::<Vec<BasicMetadataValueEnum>>();
+
+                        let func = &ns.functions[*ast_func_no];
+
+                        if !res.is_empty() {
+                            for v in func.returns.iter() {
+                                parms.push(if ns.target == Target::Solana {
+                                    bin.build_alloca(
+                                        function,
+                                        bin.llvm_var_ty(&v.ty, ns),
+                                        v.name_as_str(),
+                                    )
+                                    .into()
+                                } else {
+                                    bin.builder
+                                        .build_alloca(bin.llvm_var_ty(&v.ty, ns), v.name_as_str())
+                                        .into()
+                                });
+                            }
+                        }
+
+                        let ret = self.builtin_function(bin, func, &parms, ns);
+
+                        let success = bin.builder.build_int_compare(
+                            IntPredicate::EQ,
+                            ret.into_int_value(),
+                            bin.return_values[&ReturnCode::Success],
+                            "success",
+                        );
+
+                        let success_block = bin.context.append_basic_block(function, "success");
+                        let bail_block = bin.context.append_basic_block(function, "bail");
+                        bin.builder
+                            .build_conditional_branch(success, success_block, bail_block);
+
+                        bin.builder.position_at_end(bail_block);
+
+                        bin.builder.build_return(Some(&ret));
+                        bin.builder.position_at_end(success_block);
+
+                        if !res.is_empty() {
+                            for (i, v) in func.returns.iter().enumerate() {
+                                let val = bin.builder.build_load(
+                                    parms[args.len() + i].into_pointer_value(),
+                                    v.name_as_str(),
+                                );
+
+                                let dest = w.vars[&res[i]].value;
+
+                                if dest.is_pointer_value()
+                                    && !(v.ty.is_reference_type(ns)
+                                        || matches!(v.ty, Type::ExternalFunction { .. }))
+                                {
+                                    bin.builder.build_store(dest.into_pointer_value(), val);
+                                } else {
+                                    w.vars.get_mut(&res[i]).unwrap().value = val;
+                                }
+                            }
+                        }
+                    }
                     Instr::Call {
                     Instr::Call {
                         res,
                         res,
                         call: InternalCallTy::Dynamic(call_expr),
                         call: InternalCallTy::Dynamic(call_expr),

+ 196 - 23
src/emit/solana.rs

@@ -73,7 +73,7 @@ impl SolanaTarget {
             context.i64_type().const_int(2u64 << 32, false),
             context.i64_type().const_int(2u64 << 32, false),
         );
         );
         // externals
         // externals
-        target.declare_externals(&mut binary);
+        target.declare_externals(&mut binary, ns);
 
 
         target.emit_functions(&mut binary, contract, ns);
         target.emit_functions(&mut binary, contract, ns);
 
 
@@ -151,7 +151,7 @@ impl SolanaTarget {
         );
         );
 
 
         // externals
         // externals
-        target.declare_externals(&mut binary);
+        target.declare_externals(&mut binary, namespaces[0]);
 
 
         let mut contracts: Vec<Contract> = Vec::new();
         let mut contracts: Vec<Contract> = Vec::new();
 
 
@@ -204,6 +204,8 @@ impl SolanaTarget {
             "sol_alloc_free_",
             "sol_alloc_free_",
             "sol_get_return_data",
             "sol_get_return_data",
             "sol_set_return_data",
             "sol_set_return_data",
+            "sol_create_program_address",
+            "sol_try_find_program_address",
             "sol_sha256",
             "sol_sha256",
             "sol_keccak256",
             "sol_keccak256",
             "sol_log_data",
             "sol_log_data",
@@ -212,11 +214,17 @@ impl SolanaTarget {
         binary
         binary
     }
     }
 
 
-    fn declare_externals(&self, binary: &mut Binary) {
+    fn declare_externals(&self, binary: &mut Binary, ns: &ast::Namespace) {
         let void_ty = binary.context.void_type();
         let void_ty = binary.context.void_type();
         let u8_ptr = binary.context.i8_type().ptr_type(AddressSpace::Generic);
         let u8_ptr = binary.context.i8_type().ptr_type(AddressSpace::Generic);
         let u64_ty = binary.context.i64_type();
         let u64_ty = binary.context.i64_type();
         let u32_ty = binary.context.i32_type();
         let u32_ty = binary.context.i32_type();
+        let address = binary.address_type(ns).ptr_type(AddressSpace::Generic);
+        let seeds = binary.llvm_type(
+            &Type::Ref(Box::new(Type::Slice(Box::new(Type::Bytes(1))))),
+            ns,
+        );
+
         let sol_bytes = binary
         let sol_bytes = binary
             .context
             .context
             .struct_type(&[u8_ptr.into(), u64_ty.into()], false)
             .struct_type(&[u8_ptr.into(), u64_ty.into()], false)
@@ -309,6 +317,36 @@ impl SolanaTarget {
         function
         function
             .as_global_value()
             .as_global_value()
             .set_unnamed_address(UnnamedAddress::Local);
             .set_unnamed_address(UnnamedAddress::Local);
+
+        let function = binary.module.add_function(
+            "sol_create_program_address",
+            u64_ty.fn_type(
+                &[seeds.into(), u64_ty.into(), address.into(), address.into()],
+                false,
+            ),
+            None,
+        );
+        function
+            .as_global_value()
+            .set_unnamed_address(UnnamedAddress::Local);
+
+        let function = binary.module.add_function(
+            "sol_try_find_program_address",
+            u64_ty.fn_type(
+                &[
+                    seeds.into(),
+                    u64_ty.into(),
+                    address.into(),
+                    address.into(),
+                    u8_ptr.into(),
+                ],
+                false,
+            ),
+            None,
+        );
+        function
+            .as_global_value()
+            .set_unnamed_address(UnnamedAddress::Local);
     }
     }
 
 
     /// Returns the SolAccountInfo of the executing binary
     /// Returns the SolAccountInfo of the executing binary
@@ -807,7 +845,7 @@ impl SolanaTarget {
             let mut free_array = None;
             let mut free_array = None;
 
 
             if elem_ty.is_dynamic(ns) || zero {
             if elem_ty.is_dynamic(ns) || zero {
-                let length = if let Some(length) = dim.last().unwrap().as_ref() {
+                let length = if let Some(ast::ArrayLength::Fixed(length)) = dim.last() {
                     binary
                     binary
                         .context
                         .context
                         .i32_type()
                         .i32_type()
@@ -1511,20 +1549,16 @@ impl SolanaTarget {
             ),
             ),
             // data
             // data
             2 => {
             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_len = binary
+                    .builder
+                    .build_load(
+                        binary
+                            .builder
+                            .build_struct_gep(account_info, 2, "data_len")
+                            .unwrap(),
+                        "data_len",
+                    )
+                    .into_int_value();
 
 
                 let data = binary.builder.build_load(
                 let data = binary.builder.build_load(
                     binary
                     binary
@@ -1536,7 +1570,7 @@ impl SolanaTarget {
 
 
                 let slice_alloca = binary.build_alloca(
                 let slice_alloca = binary.build_alloca(
                     function,
                     function,
-                    binary.llvm_type(&ast::Type::Slice, ns),
+                    binary.llvm_type(&ast::Type::Slice(Box::new(Type::Bytes(1))), ns),
                     "slice_alloca",
                     "slice_alloca",
                 );
                 );
                 let data_elem = binary
                 let data_elem = binary
@@ -2252,7 +2286,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 let length;
                 let length;
                 let mut slot = *slot;
                 let mut slot = *slot;
 
 
-                if dim.last().unwrap().is_some() {
+                if matches!(dim.last().unwrap(), ast::ArrayLength::Fixed(_)) {
                     // LLVMSizeOf() produces an i64 and malloc takes i32
                     // LLVMSizeOf() produces an i64 and malloc takes i32
                     let size = binary.builder.build_int_truncate(
                     let size = binary.builder.build_int_truncate(
                         llvm_ty.size_of().unwrap(),
                         llvm_ty.size_of().unwrap(),
@@ -2278,7 +2312,11 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         "dest",
                         "dest",
                     );
                     );
                     length = binary.context.i32_type().const_int(
                     length = binary.context.i32_type().const_int(
-                        dim.last().unwrap().as_ref().unwrap().to_u64().unwrap(),
+                        if let Some(ast::ArrayLength::Fixed(d)) = dim.last() {
+                            d.to_u64().unwrap()
+                        } else {
+                            unreachable!()
+                        },
                         false,
                         false,
                     );
                     );
                 } else {
                 } else {
@@ -2553,7 +2591,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 "offset_ptr",
                 "offset_ptr",
             );
             );
 
 
-            let length = if let Some(length) = dim.last().unwrap().as_ref() {
+            let length = if let Some(ast::ArrayLength::Fixed(length)) = dim.last() {
                 binary
                 binary
                     .context
                     .context
                     .i32_type()
                     .i32_type()
@@ -2564,7 +2602,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
 
             let mut elem_slot = *offset;
             let mut elem_slot = *offset;
 
 
-            if dim.last().unwrap().is_none() {
+            if Some(&ast::ArrayLength::Dynamic) == dim.last() {
                 // reallocate to the right size
                 // reallocate to the right size
                 let member_size = binary
                 let member_size = binary
                     .context
                     .context
@@ -3034,6 +3072,119 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         }
         }
     }
     }
 
 
+    fn builtin_function(
+        &self,
+        binary: &Binary<'a>,
+        func: &ast::Function,
+        args: &[BasicMetadataValueEnum<'a>],
+        ns: &ast::Namespace,
+    ) -> BasicValueEnum<'a> {
+        if func.name == "create_program_address" {
+            let func = binary
+                .module
+                .get_function("sol_create_program_address")
+                .unwrap();
+
+            // first argument are the seeds
+            let seeds = binary.builder.build_pointer_cast(
+                args[0].into_pointer_value(),
+                func.get_first_param()
+                    .unwrap()
+                    .get_type()
+                    .into_pointer_type(),
+                "seeds",
+            );
+
+            let seed_count = binary.context.i64_type().const_int(
+                args[0]
+                    .into_pointer_value()
+                    .get_type()
+                    .get_element_type()
+                    .into_array_type()
+                    .len() as u64,
+                false,
+            );
+
+            // address
+            let address = binary
+                .builder
+                .build_alloca(binary.address_type(ns), "address");
+
+            binary
+                .builder
+                .build_store(address, args[1].into_array_value());
+
+            binary
+                .builder
+                .build_call(
+                    func,
+                    &[
+                        seeds.into(),
+                        seed_count.into(),
+                        address.into(),
+                        args[2], // return value
+                    ],
+                    "",
+                )
+                .try_as_basic_value()
+                .left()
+                .unwrap()
+        } else if func.name == "try_find_program_address" {
+            let func = binary
+                .module
+                .get_function("sol_try_find_program_address")
+                .unwrap();
+
+            // first argument are the seeds
+            let seeds = binary.builder.build_pointer_cast(
+                args[0].into_pointer_value(),
+                func.get_first_param()
+                    .unwrap()
+                    .get_type()
+                    .into_pointer_type(),
+                "seeds",
+            );
+
+            let seed_count = binary.context.i64_type().const_int(
+                args[0]
+                    .into_pointer_value()
+                    .get_type()
+                    .get_element_type()
+                    .into_array_type()
+                    .len() as u64,
+                false,
+            );
+
+            // address
+            let address = binary
+                .builder
+                .build_alloca(binary.address_type(ns), "address");
+
+            binary
+                .builder
+                .build_store(address, args[1].into_array_value());
+
+            binary
+                .builder
+                .build_call(
+                    func,
+                    &[
+                        seeds.into(),
+                        seed_count.into(),
+                        address.into(),
+                        args[2], // return address/pubkey
+                        args[3], // return seed bump
+                    ],
+                    "",
+                )
+                .try_as_basic_value()
+                .left()
+                .unwrap()
+        } else {
+            unreachable!();
+        }
+    }
+
     /// Call external binary
     /// Call external binary
     fn external_call<'b>(
     fn external_call<'b>(
         &self,
         &self,
@@ -3631,6 +3782,28 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
 
                 binary.builder.build_load(value, "self_address")
                 binary.builder.build_load(value, "self_address")
             }
             }
+            codegen::Expression::Builtin(_, _, codegen::Builtin::ProgramId, _) => {
+                let parameters = self.sol_parameters(binary);
+
+                let account_id = binary
+                    .builder
+                    .build_load(
+                        binary
+                            .builder
+                            .build_struct_gep(parameters, 7, "program_id")
+                            .unwrap(),
+                        "program_id",
+                    )
+                    .into_pointer_value();
+
+                let value = binary.builder.build_pointer_cast(
+                    account_id,
+                    binary.address_type(ns).ptr_type(AddressSpace::Generic),
+                    "",
+                );
+
+                binary.builder.build_load(value, "program_id")
+            }
             codegen::Expression::Builtin(_, _, codegen::Builtin::Calldata, _) => {
             codegen::Expression::Builtin(_, _, codegen::Builtin::Calldata, _) => {
                 let sol_params = self.sol_parameters(binary);
                 let sol_params = self.sol_parameters(binary);
 
 

+ 11 - 9
src/emit/substrate.rs

@@ -800,7 +800,7 @@ impl SubstrateTarget {
                 dest.into()
                 dest.into()
             }
             }
             ast::Type::Array(_, dim) => {
             ast::Type::Array(_, dim) => {
-                if let Some(d) = &dim.last().unwrap() {
+                if let Some(ast::ArrayLength::Fixed(d)) = dim.last() {
                     let llvm_ty = binary.llvm_type(ty.deref_any(), ns);
                     let llvm_ty = binary.llvm_type(ty.deref_any(), ns);
 
 
                     let size = llvm_ty
                     let size = llvm_ty
@@ -1216,7 +1216,7 @@ impl SubstrateTarget {
                 arg,
                 arg,
                 data,
                 data,
             ),
             ),
-            ast::Type::Array(_, dim) if dim.last().unwrap().is_some() => {
+            ast::Type::Array(_, dim) if matches!(dim.last(), Some(ast::ArrayLength::Fixed(_))) => {
                 let arg = if load {
                 let arg = if load {
                     binary
                     binary
                         .builder
                         .builder
@@ -1230,7 +1230,7 @@ impl SubstrateTarget {
                 let normal_array = binary.context.append_basic_block(function, "normal_array");
                 let normal_array = binary.context.append_basic_block(function, "normal_array");
                 let done_array = binary.context.append_basic_block(function, "done_array");
                 let done_array = binary.context.append_basic_block(function, "done_array");
 
 
-                let dim = dim.last().unwrap().as_ref().unwrap().to_u64().unwrap();
+                let dim = ty.array_length().unwrap().to_u64().unwrap();
 
 
                 let elem_ty = ty.array_deref();
                 let elem_ty = ty.array_deref();
 
 
@@ -1690,11 +1690,13 @@ impl SubstrateTarget {
 
 
                 sum.as_basic_value().into_int_value()
                 sum.as_basic_value().into_int_value()
             }
             }
-            ast::Type::Array(_, dims) if dims.last().unwrap().is_some() => {
-                let array_length = binary.context.i32_type().const_int(
-                    dims.last().unwrap().as_ref().unwrap().to_u64().unwrap(),
-                    false,
-                );
+            ast::Type::Array(_, dims)
+                if matches!(dims.last(), Some(ast::ArrayLength::Fixed(_))) =>
+            {
+                let array_length = binary
+                    .context
+                    .i32_type()
+                    .const_int(ty.array_length().unwrap().to_u64().unwrap(), false);
 
 
                 let elem_ty = ty.array_deref();
                 let elem_ty = ty.array_deref();
 
 
@@ -1811,7 +1813,7 @@ impl SubstrateTarget {
                     )
                     )
                 }
                 }
             }
             }
-            ast::Type::Array(_, dims) if dims.last().unwrap().is_none() => {
+            ast::Type::Array(_, dims) if dims.last() == Some(&ast::ArrayLength::Dynamic) => {
                 let arg = if load {
                 let arg = if load {
                     binary.builder.build_load(arg.into_pointer_value(), "")
                     binary.builder.build_load(arg.into_pointer_value(), "")
                 } else {
                 } else {

+ 26 - 2
src/sema/ast.rs

@@ -27,7 +27,7 @@ pub enum Type {
     Bytes(u8),
     Bytes(u8),
     DynamicBytes,
     DynamicBytes,
     String,
     String,
-    Array(Box<Type>, Vec<Option<BigInt>>),
+    Array(Box<Type>, Vec<ArrayLength>),
     /// The usize is an index into enums in the namespace
     /// The usize is an index into enums in the namespace
     Enum(usize),
     Enum(usize),
     /// The usize is an index into contracts in the namespace
     /// The usize is an index into contracts in the namespace
@@ -56,11 +56,34 @@ pub enum Type {
     Void,
     Void,
     Unreachable,
     Unreachable,
     /// DynamicBytes and String are lowered to a vector.
     /// DynamicBytes and String are lowered to a vector.
-    Slice,
+    Slice(Box<Type>),
     /// We could not resolve this type
     /// We could not resolve this type
     Unresolved,
     Unresolved,
 }
 }
 
 
+#[derive(PartialEq, Clone, Eq, Hash, Debug)]
+pub enum ArrayLength {
+    Fixed(BigInt),
+    Dynamic,
+    /// Fixed length arrays, any length permitted. This is useful for when we
+    /// do not want dynamic length, but want to permit any length. For example
+    /// the create_program_address() call takes any number of seeds as its
+    /// first argument, and we don't want to allocate a dynamic array for
+    /// this parameter as this would be wasteful to allocate a vector for
+    /// this argument.
+    AnyFixed,
+}
+
+impl ArrayLength {
+    /// Get the length, if fixed
+    pub fn array_length(&self) -> Option<&BigInt> {
+        match self {
+            ArrayLength::Fixed(len) => Some(len),
+            _ => None,
+        }
+    }
+}
+
 pub trait RetrieveType {
 pub trait RetrieveType {
     /// Return the type for this expression. This assumes the expression has a single value,
     /// Return the type for this expression. This assumes the expression has a single value,
     /// panics will occur otherwise
     /// panics will occur otherwise
@@ -1000,6 +1023,7 @@ pub enum Builtin {
     GasLimit,
     GasLimit,
     BlockNumber,
     BlockNumber,
     Slot,
     Slot,
+    ProgramId,
     Timestamp,
     Timestamp,
     Calldata,
     Calldata,
     Sender,
     Sender,

+ 150 - 5
src/sema/builtin.rs

@@ -1,6 +1,6 @@
 use super::ast::{
 use super::ast::{
-    Builtin, BuiltinStruct, Diagnostic, Expression, File, Namespace, Parameter, StructDecl, Symbol,
-    Type,
+    ArrayLength, Builtin, BuiltinStruct, Diagnostic, Expression, File, Function, Namespace,
+    Parameter, StructDecl, Symbol, Type,
 };
 };
 use super::diagnostics::Diagnostics;
 use super::diagnostics::Diagnostics;
 use super::eval::eval_const_number;
 use super::eval::eval_const_number;
@@ -11,8 +11,8 @@ use crate::Target;
 use num_bigint::BigInt;
 use num_bigint::BigInt;
 use num_traits::One;
 use num_traits::One;
 use once_cell::sync::Lazy;
 use once_cell::sync::Lazy;
-use solang_parser::pt;
 use solang_parser::pt::CodeLocation;
 use solang_parser::pt::CodeLocation;
+use solang_parser::pt::{self, Identifier};
 use std::path::PathBuf;
 use std::path::PathBuf;
 
 
 pub struct Prototype {
 pub struct Prototype {
@@ -339,7 +339,7 @@ static BUILTIN_FUNCTIONS: Lazy<[Prototype; 27]> = Lazy::new(|| {
 });
 });
 
 
 // A list of all Solidity builtins variables
 // A list of all Solidity builtins variables
-static BUILTIN_VARIABLE: Lazy<[Prototype; 15]> = Lazy::new(|| {
+static BUILTIN_VARIABLE: Lazy<[Prototype; 16]> = Lazy::new(|| {
     [
     [
         Prototype {
         Prototype {
             builtin: Builtin::BlockCoinbase,
             builtin: Builtin::BlockCoinbase,
@@ -396,6 +396,17 @@ static BUILTIN_VARIABLE: Lazy<[Prototype; 15]> = Lazy::new(|| {
             doc: "Current slot number",
             doc: "Current slot number",
             constant: false,
             constant: false,
         },
         },
+        Prototype {
+            builtin: Builtin::ProgramId,
+            namespace: Some("tx"),
+            method: None,
+            name: "program_id",
+            params: vec![],
+            ret: vec![Type::Address(false)],
+            target: vec![Target::Solana],
+            doc: "Program ID of currently executing program",
+            constant: false,
+        },
         Prototype {
         Prototype {
             builtin: Builtin::Timestamp,
             builtin: Builtin::Timestamp,
             namespace: Some("block"),
             namespace: Some("block"),
@@ -501,7 +512,10 @@ static BUILTIN_VARIABLE: Lazy<[Prototype; 15]> = Lazy::new(|| {
             method: None,
             method: None,
             name: "accounts",
             name: "accounts",
             params: vec![],
             params: vec![],
-            ret: vec![Type::Array(Box::new(Type::Struct(0)), vec![None])],
+            ret: vec![Type::Array(
+                Box::new(Type::Struct(0)),
+                vec![ArrayLength::Dynamic],
+            )],
             target: vec![Target::Solana],
             target: vec![Target::Solana],
             doc: "Accounts passed into transaction",
             doc: "Accounts passed into transaction",
             constant: false,
             constant: false,
@@ -1608,5 +1622,136 @@ impl Namespace {
             &id,
             &id,
             Symbol::Struct(pt::Loc::Builtin, account_meta_no)
             Symbol::Struct(pt::Loc::Builtin, account_meta_no)
         ));
         ));
+
+        let mut func = Function::new(
+            pt::Loc::Builtin,
+            "create_program_address".to_string(),
+            None,
+            Vec::new(),
+            pt::FunctionTy::Function,
+            None,
+            pt::Visibility::Public(None),
+            vec![
+                Parameter {
+                    loc: pt::Loc::Builtin,
+                    id: None,
+                    ty: Type::Array(
+                        Box::new(Type::Slice(Box::new(Type::Bytes(1)))),
+                        vec![ArrayLength::AnyFixed],
+                    ),
+                    ty_loc: None,
+                    readonly: false,
+                    indexed: false,
+                    recursive: false,
+                },
+                Parameter {
+                    loc: pt::Loc::Builtin,
+                    id: None,
+                    ty: Type::Address(false),
+                    ty_loc: None,
+                    readonly: false,
+                    indexed: false,
+                    recursive: false,
+                },
+            ],
+            vec![Parameter {
+                loc: pt::Loc::Builtin,
+                id: None,
+                ty: Type::Address(false),
+                ty_loc: None,
+                readonly: false,
+                indexed: false,
+                recursive: false,
+            }],
+            self,
+        );
+
+        func.has_body = true;
+
+        let func_no = self.functions.len();
+        let id = Identifier {
+            name: func.name.to_owned(),
+            loc: pt::Loc::Builtin,
+        };
+
+        self.functions.push(func);
+
+        assert!(self.add_symbol(
+            file_no,
+            None,
+            &id,
+            Symbol::Function(vec![(pt::Loc::Builtin, func_no)])
+        ));
+
+        let mut func = Function::new(
+            pt::Loc::Builtin,
+            "try_find_program_address".to_string(),
+            None,
+            Vec::new(),
+            pt::FunctionTy::Function,
+            None,
+            pt::Visibility::Public(None),
+            vec![
+                Parameter {
+                    loc: pt::Loc::Builtin,
+                    id: None,
+                    ty: Type::Array(
+                        Box::new(Type::Slice(Box::new(Type::Bytes(1)))),
+                        vec![ArrayLength::AnyFixed],
+                    ),
+                    ty_loc: None,
+                    readonly: false,
+                    indexed: false,
+                    recursive: false,
+                },
+                Parameter {
+                    loc: pt::Loc::Builtin,
+                    id: None,
+                    ty: Type::Address(false),
+                    ty_loc: None,
+                    readonly: false,
+                    indexed: false,
+                    recursive: false,
+                },
+            ],
+            vec![
+                Parameter {
+                    loc: pt::Loc::Builtin,
+                    id: None,
+                    ty: Type::Address(false),
+                    ty_loc: None,
+                    readonly: false,
+                    indexed: false,
+                    recursive: false,
+                },
+                Parameter {
+                    loc: pt::Loc::Builtin,
+                    id: None,
+                    ty: Type::Bytes(1),
+                    ty_loc: None,
+                    readonly: false,
+                    indexed: false,
+                    recursive: false,
+                },
+            ],
+            self,
+        );
+
+        func.has_body = true;
+
+        let func_no = self.functions.len();
+        let id = Identifier {
+            name: func.name.to_owned(),
+            loc: pt::Loc::Builtin,
+        };
+
+        self.functions.push(func);
+
+        assert!(self.add_symbol(
+            file_no,
+            None,
+            &id,
+            Symbol::Function(vec![(pt::Loc::Builtin, func_no)])
+        ));
     }
     }
 }
 }

+ 6 - 2
src/sema/dotgraphviz.rs

@@ -2166,11 +2166,15 @@ impl Namespace {
         }
         }
 
 
         // free functions
         // free functions
-        if !self.functions.iter().any(|func| func.contract_no.is_some()) {
+        if self
+            .functions
+            .iter()
+            .any(|func| func.contract_no.is_none() && func.loc != pt::Loc::Builtin)
+        {
             let functions = dot.add_node(Node::new("free_functions", Vec::new()), None, None);
             let functions = dot.add_node(Node::new("free_functions", Vec::new()), None, None);
 
 
             for func in &self.functions {
             for func in &self.functions {
-                if func.contract_no.is_none() {
+                if func.contract_no.is_none() && func.loc != pt::Loc::Builtin {
                     dot.add_function(func, self, functions);
                     dot.add_function(func, self, functions);
                 }
                 }
             }
             }

+ 79 - 23
src/sema/expression.rs

@@ -1,7 +1,7 @@
 use super::address::to_hexstr_eip55;
 use super::address::to_hexstr_eip55;
 use super::ast::{
 use super::ast::{
-    Builtin, BuiltinStruct, CallArgs, CallTy, Diagnostic, Expression, Function, Mutability,
-    Namespace, StringLocation, Symbol, Type,
+    ArrayLength, Builtin, BuiltinStruct, CallArgs, CallTy, Diagnostic, Expression, Function,
+    Mutability, Namespace, StringLocation, Symbol, Type,
 };
 };
 use super::builtin;
 use super::builtin;
 use super::contracts::is_base;
 use super::contracts::is_base;
@@ -1061,6 +1061,20 @@ impl Expression {
                     Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
                     Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
                 }
                 }
             }
             }
+            // Match any array with ArrayLength::AnyFixed if is it fixed for that dimension, and the
+            // element type and other dimensions also match
+            (Type::Array(from_elem, from_dim), Type::Array(to_elem, to_dim))
+                if from_elem == to_elem
+                    && from_dim.len() == to_dim.len()
+                    && from_dim.iter().zip(to_dim.iter()).all(|(f, t)| {
+                        f == t || matches!((f, t), (ArrayLength::Fixed(_), ArrayLength::AnyFixed))
+                    }) =>
+            {
+                Ok(self.clone())
+            }
+            (Type::DynamicBytes, Type::Slice(ty)) if ty.as_ref() == &Type::Bytes(1) => {
+                Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+            }
             _ => {
             _ => {
                 diagnostics.push(Diagnostic::cast_error(
                 diagnostics.push(Diagnostic::cast_error(
                     *loc,
                     *loc,
@@ -1640,7 +1654,7 @@ pub fn expression(
         pt::Expression::StringLiteral(v) => {
         pt::Expression::StringLiteral(v) => {
             Ok(string_literal(v, context.file_no, diagnostics, resolve_to))
             Ok(string_literal(v, context.file_no, diagnostics, resolve_to))
         }
         }
-        pt::Expression::HexLiteral(v) => hex_literal(v, diagnostics),
+        pt::Expression::HexLiteral(v) => hex_literal(v, diagnostics, resolve_to),
         pt::Expression::NumberLiteral(loc, integer, exp) => number_literal(
         pt::Expression::NumberLiteral(loc, integer, exp) => number_literal(
             loc,
             loc,
             integer,
             integer,
@@ -2200,8 +2214,8 @@ fn string_literal(
 
 
     let length = result.len();
     let length = result.len();
 
 
-    if let ResolveTo::Type(Type::String) = resolve_to {
-        Expression::AllocDynamicArray(
+    match resolve_to {
+        ResolveTo::Type(Type::String) => Expression::AllocDynamicArray(
             loc,
             loc,
             Type::String,
             Type::String,
             Box::new(Expression::NumberLiteral(
             Box::new(Expression::NumberLiteral(
@@ -2210,13 +2224,28 @@ fn string_literal(
                 BigInt::from(length),
                 BigInt::from(length),
             )),
             )),
             Some(result),
             Some(result),
-        )
-    } else {
-        Expression::BytesLiteral(loc, Type::Bytes(length as u8), result)
+        ),
+        ResolveTo::Type(Type::Slice(ty)) if ty.as_ref() == &Type::Bytes(1) => {
+            Expression::AllocDynamicArray(
+                loc,
+                Type::Slice(ty.clone()),
+                Box::new(Expression::NumberLiteral(
+                    loc,
+                    Type::Uint(32),
+                    BigInt::from(length),
+                )),
+                Some(result),
+            )
+        }
+        _ => Expression::BytesLiteral(loc, Type::Bytes(length as u8), result),
     }
     }
 }
 }
 
 
-fn hex_literal(v: &[pt::HexLiteral], diagnostics: &mut Diagnostics) -> Result<Expression, ()> {
+fn hex_literal(
+    v: &[pt::HexLiteral],
+    diagnostics: &mut Diagnostics,
+    resolve_to: ResolveTo,
+) -> Result<Expression, ()> {
     let mut result = Vec::new();
     let mut result = Vec::new();
     let mut loc = v[0].loc;
     let mut loc = v[0].loc;
 
 
@@ -2235,11 +2264,35 @@ fn hex_literal(v: &[pt::HexLiteral], diagnostics: &mut Diagnostics) -> Result<Ex
 
 
     let length = result.len();
     let length = result.len();
 
 
-    Ok(Expression::BytesLiteral(
-        loc,
-        Type::Bytes(length as u8),
-        result,
-    ))
+    match resolve_to {
+        ResolveTo::Type(Type::Slice(ty)) if ty.as_ref() == &Type::Bytes(1) => {
+            Ok(Expression::AllocDynamicArray(
+                loc,
+                Type::Slice(ty.clone()),
+                Box::new(Expression::NumberLiteral(
+                    loc,
+                    Type::Uint(32),
+                    BigInt::from(length),
+                )),
+                Some(result),
+            ))
+        }
+        ResolveTo::Type(Type::DynamicBytes) => Ok(Expression::AllocDynamicArray(
+            loc,
+            Type::DynamicBytes,
+            Box::new(Expression::NumberLiteral(
+                loc,
+                Type::Uint(32),
+                BigInt::from(length),
+            )),
+            Some(result),
+        )),
+        _ => Ok(Expression::BytesLiteral(
+            loc,
+            Type::Bytes(length as u8),
+            result,
+        )),
+    }
 }
 }
 
 
 fn hex_number_literal(
 fn hex_number_literal(
@@ -3551,7 +3604,7 @@ pub fn new(
 
 
     match &ty {
     match &ty {
         Type::Array(ty, dim) => {
         Type::Array(ty, dim) => {
-            if dim.last().unwrap().is_some() {
+            if matches!(dim.last(), Some(ArrayLength::Fixed(_))) {
                 diagnostics.push(Diagnostic::error(
                 diagnostics.push(Diagnostic::error(
                     *loc,
                     *loc,
                     format!(
                     format!(
@@ -4591,13 +4644,13 @@ fn member_access(
         Type::Array(_, dim) => {
         Type::Array(_, dim) => {
             if id.name == "length" {
             if id.name == "length" {
                 return match dim.last().unwrap() {
                 return match dim.last().unwrap() {
-                    None => Ok(Expression::Builtin(
+                    ArrayLength::Dynamic => Ok(Expression::Builtin(
                         *loc,
                         *loc,
                         vec![Type::Uint(32)],
                         vec![Type::Uint(32)],
                         Builtin::ArrayLength,
                         Builtin::ArrayLength,
                         vec![expr],
                         vec![expr],
                     )),
                     )),
-                    Some(d) => {
+                    ArrayLength::Fixed(d) => {
                         //We should not eliminate an array from the code when 'length' is called
                         //We should not eliminate an array from the code when 'length' is called
                         //So the variable is also assigned a value to be read from 'length'
                         //So the variable is also assigned a value to be read from 'length'
                         assigned_variable(ns, &expr, symtable);
                         assigned_variable(ns, &expr, symtable);
@@ -4610,6 +4663,7 @@ fn member_access(
                             ResolveTo::Type(&Type::Uint(32)),
                             ResolveTo::Type(&Type::Uint(32)),
                         )
                         )
                     }
                     }
+                    ArrayLength::AnyFixed => unreachable!(),
                 };
                 };
             }
             }
         }
         }
@@ -4652,7 +4706,7 @@ fn member_access(
                 if id.name == "length" {
                 if id.name == "length" {
                     let elem_ty = expr.ty().storage_array_elem().deref_into();
                     let elem_ty = expr.ty().storage_array_elem().deref_into();
 
 
-                    if let Some(dim) = &dim.last().unwrap() {
+                    if let Some(ArrayLength::Fixed(dim)) = dim.last() {
                         // sparse array could be large than ns.storage_type() on Solana
                         // sparse array could be large than ns.storage_type() on Solana
                         if dim.bits() > ns.storage_type().bits(ns) as u64 {
                         if dim.bits() > ns.storage_type().bits(ns) as u64 {
                             return Ok(Expression::StorageArrayLength {
                             return Ok(Expression::StorageArrayLength {
@@ -5943,7 +5997,7 @@ fn method_call_pos_args(
                 }
                 }
 
 
                 if func.name == "push" {
                 if func.name == "push" {
-                    if dim.last().unwrap().is_some() {
+                    if matches!(dim.last(), Some(ArrayLength::Fixed(_))) {
                         diagnostics.push(Diagnostic::error(
                         diagnostics.push(Diagnostic::error(
                             func.loc,
                             func.loc,
                             "method 'push()' not allowed on fixed length array".to_string(),
                             "method 'push()' not allowed on fixed length array".to_string(),
@@ -5999,7 +6053,7 @@ fn method_call_pos_args(
                     ));
                     ));
                 }
                 }
                 if func.name == "pop" {
                 if func.name == "pop" {
-                    if dim.last().unwrap().is_some() {
+                    if matches!(dim.last(), Some(ArrayLength::Fixed(_))) {
                         diagnostics.push(Diagnostic::error(
                         diagnostics.push(Diagnostic::error(
                             func.loc,
                             func.loc,
                             "method 'pop()' not allowed on fixed length array".to_string(),
                             "method 'pop()' not allowed on fixed length array".to_string(),
@@ -6918,7 +6972,7 @@ fn array_literal(
 
 
     // We follow the solidity scheme were everthing gets implicitly converted to the
     // We follow the solidity scheme were everthing gets implicitly converted to the
     // type of the first element
     // type of the first element
-    let first = expression(
+    let mut first = expression(
         flattened.next().unwrap(),
         flattened.next().unwrap(),
         context,
         context,
         ns,
         ns,
@@ -6928,6 +6982,8 @@ fn array_literal(
     )?;
     )?;
 
 
     let ty = if let ResolveTo::Type(ty) = resolve_to {
     let ty = if let ResolveTo::Type(ty) = resolve_to {
+        first = first.cast(&first.loc(), ty, true, ns, diagnostics)?;
+
         ty.clone()
         ty.clone()
     } else {
     } else {
         first.ty()
         first.ty()
@@ -6950,8 +7006,8 @@ fn array_literal(
     let aty = Type::Array(
     let aty = Type::Array(
         Box::new(ty),
         Box::new(ty),
         dims.iter()
         dims.iter()
-            .map(|n| Some(BigInt::from_u32(*n).unwrap()))
-            .collect::<Vec<Option<BigInt>>>(),
+            .map(|n| ArrayLength::Fixed(BigInt::from_u32(*n).unwrap()))
+            .collect::<Vec<ArrayLength>>(),
     );
     );
 
 
     if context.constant {
     if context.constant {

+ 1 - 0
src/sema/mutability.rs

@@ -246,6 +246,7 @@ fn read_expression(expr: &Expression, state: &mut StateCheck) -> bool {
         Expression::Builtin(loc, _, Builtin::GetAddress, _)
         Expression::Builtin(loc, _, Builtin::GetAddress, _)
         | Expression::Builtin(loc, _, Builtin::BlockNumber, _)
         | Expression::Builtin(loc, _, Builtin::BlockNumber, _)
         | Expression::Builtin(loc, _, Builtin::Timestamp, _)
         | Expression::Builtin(loc, _, Builtin::Timestamp, _)
+        | Expression::Builtin(loc, _, Builtin::ProgramId, _)
         | Expression::Builtin(loc, _, Builtin::BlockCoinbase, _)
         | Expression::Builtin(loc, _, Builtin::BlockCoinbase, _)
         | Expression::Builtin(loc, _, Builtin::BlockDifficulty, _)
         | Expression::Builtin(loc, _, Builtin::BlockDifficulty, _)
         | Expression::Builtin(loc, _, Builtin::BlockHash, _)
         | Expression::Builtin(loc, _, Builtin::BlockHash, _)

+ 6 - 4
src/sema/namespace.rs

@@ -1,5 +1,7 @@
 use super::{
 use super::{
-    ast::{Diagnostic, Mutability, Namespace, Note, Parameter, RetrieveType, Symbol, Type},
+    ast::{
+        ArrayLength, Diagnostic, Mutability, Namespace, Note, Parameter, RetrieveType, Symbol, Type,
+    },
     builtin,
     builtin,
     diagnostics::Diagnostics,
     diagnostics::Diagnostics,
     eval::eval_const_number,
     eval::eval_const_number,
@@ -757,7 +759,7 @@ impl Namespace {
         fn resolve_dimensions(
         fn resolve_dimensions(
             ast_dimensions: &[Option<(pt::Loc, BigInt)>],
             ast_dimensions: &[Option<(pt::Loc, BigInt)>],
             diagnostics: &mut Diagnostics,
             diagnostics: &mut Diagnostics,
-        ) -> Result<Vec<Option<BigInt>>, ()> {
+        ) -> Result<Vec<ArrayLength>, ()> {
             let mut dimensions = Vec::new();
             let mut dimensions = Vec::new();
 
 
             for d in ast_dimensions.iter().rev() {
             for d in ast_dimensions.iter().rev() {
@@ -775,9 +777,9 @@ impl Namespace {
                         ));
                         ));
                         return Err(());
                         return Err(());
                     }
                     }
-                    dimensions.push(Some(n.clone()));
+                    dimensions.push(ArrayLength::Fixed(n.clone()));
                 } else {
                 } else {
-                    dimensions.push(None);
+                    dimensions.push(ArrayLength::Dynamic);
                 }
                 }
             }
             }
 
 

+ 44 - 30
src/sema/types.rs

@@ -2,8 +2,8 @@ use super::tags::resolve_tags;
 use super::SOLANA_BUCKET_SIZE;
 use super::SOLANA_BUCKET_SIZE;
 use super::{
 use super::{
     ast::{
     ast::{
-        BuiltinStruct, Contract, Diagnostic, EnumDecl, EventDecl, Namespace, Parameter, StructDecl,
-        Symbol, Tag, Type, UserTypeDecl,
+        ArrayLength, BuiltinStruct, Contract, Diagnostic, EnumDecl, EventDecl, Namespace,
+        Parameter, StructDecl, Symbol, Tag, Type, UserTypeDecl,
     },
     },
     diagnostics::Diagnostics,
     diagnostics::Diagnostics,
     SOLANA_SPARSE_ARRAY_SIZE,
     SOLANA_SPARSE_ARRAY_SIZE,
@@ -794,9 +794,9 @@ impl Type {
                 "{}{}",
                 "{}{}",
                 ty.to_string(ns),
                 ty.to_string(ns),
                 len.iter()
                 len.iter()
-                    .map(|l| match l {
-                        None => "[]".to_string(),
-                        Some(l) => format!("[{}]", l),
+                    .map(|len| match len {
+                        ArrayLength::Fixed(len) => format!("[{}]", len),
+                        _ => "[]".to_string(),
                     })
                     })
                     .collect::<String>()
                     .collect::<String>()
             ),
             ),
@@ -850,7 +850,7 @@ impl Type {
             Type::StorageRef(_, ty) => format!("{} storage", ty.to_string(ns)),
             Type::StorageRef(_, ty) => format!("{} storage", ty.to_string(ns)),
             Type::Void => "void".to_owned(),
             Type::Void => "void".to_owned(),
             Type::Unreachable => "unreachable".to_owned(),
             Type::Unreachable => "unreachable".to_owned(),
-            Type::Slice => "slice".to_owned(),
+            Type::Slice(ty) => format!("{} slice", ty.to_string(ns)),
             Type::Unresolved => "unresolved".to_owned(),
             Type::Unresolved => "unresolved".to_owned(),
         }
         }
     }
     }
@@ -890,9 +890,9 @@ impl Type {
                 "{}{}",
                 "{}{}",
                 ty.to_signature_string(say_tuple, ns),
                 ty.to_signature_string(say_tuple, ns),
                 len.iter()
                 len.iter()
-                    .map(|l| match l {
-                        None => "[]".to_string(),
-                        Some(l) => format!("[{}]", l),
+                    .map(|len| match len {
+                        ArrayLength::Fixed(len) => format!("[{}]", len),
+                        _ => "[]".to_string(),
                     })
                     })
                     .collect::<String>()
                     .collect::<String>()
             ),
             ),
@@ -914,6 +914,7 @@ impl Type {
             Type::UserType(n) => ns.user_types[*n].ty.to_signature_string(say_tuple, ns),
             Type::UserType(n) => ns.user_types[*n].ty.to_signature_string(say_tuple, ns),
             // TODO: should an unresolved type not match another unresolved type?
             // TODO: should an unresolved type not match another unresolved type?
             Type::Unresolved => "unresolved".to_owned(),
             Type::Unresolved => "unresolved".to_owned(),
+            Type::Slice(ty) => format!("{} slice", ty.to_string(ns)),
             _ => unreachable!(),
             _ => unreachable!(),
         }
         }
     }
     }
@@ -945,7 +946,7 @@ impl Type {
             Type::Bytes(_) => false,
             Type::Bytes(_) => false,
             Type::Enum(_) => false,
             Type::Enum(_) => false,
             Type::Struct(_) => true,
             Type::Struct(_) => true,
-            Type::Array(_, dims) => dims.last().unwrap().is_some(),
+            Type::Array(_, dims) => matches!(dims.last(), Some(ArrayLength::Fixed(_))),
             Type::DynamicBytes => false,
             Type::DynamicBytes => false,
             Type::String => false,
             Type::String => false,
             Type::Mapping(..) => false,
             Type::Mapping(..) => false,
@@ -954,7 +955,7 @@ impl Type {
             Type::StorageRef(..) => false,
             Type::StorageRef(..) => false,
             Type::InternalFunction { .. } => false,
             Type::InternalFunction { .. } => false,
             Type::ExternalFunction { .. } => false,
             Type::ExternalFunction { .. } => false,
-            Type::Slice => false,
+            Type::Slice(_) => false,
             Type::Unresolved => false,
             Type::Unresolved => false,
             _ => unreachable!("{:?}", self),
             _ => unreachable!("{:?}", self),
         }
         }
@@ -996,7 +997,7 @@ impl Type {
         match self {
         match self {
             Type::StorageRef(_, ty) => ty.array_length(),
             Type::StorageRef(_, ty) => ty.array_length(),
             Type::Ref(ty) => ty.array_length(),
             Type::Ref(ty) => ty.array_length(),
-            Type::Array(_, dim) => dim.last().unwrap().as_ref(),
+            Type::Array(_, dim) => dim.last().unwrap().array_length(),
             _ => panic!("array_length on non-array"),
             _ => panic!("array_length on non-array"),
         }
         }
     }
     }
@@ -1016,8 +1017,9 @@ impl Type {
                 ty.memory_size_of(ns).mul(
                 ty.memory_size_of(ns).mul(
                     dims.iter()
                     dims.iter()
                         .map(|d| match d {
                         .map(|d| match d {
-                            None => &pointer_size,
-                            Some(n) => n,
+                            ArrayLength::Dynamic => &pointer_size,
+                            ArrayLength::Fixed(n) => n,
+                            ArrayLength::AnyFixed => unreachable!(),
                         })
                         })
                         .product::<BigInt>(),
                         .product::<BigInt>(),
                 )
                 )
@@ -1052,8 +1054,9 @@ impl Type {
                 ty.solana_storage_size(ns).mul(
                 ty.solana_storage_size(ns).mul(
                     dims.iter()
                     dims.iter()
                         .map(|d| match d {
                         .map(|d| match d {
-                            None => &pointer_size,
-                            Some(d) => d,
+                            ArrayLength::Dynamic => &pointer_size,
+                            ArrayLength::Fixed(d) => d,
+                            ArrayLength::AnyFixed => panic!("unknown length"),
                         })
                         })
                         .product::<BigInt>(),
                         .product::<BigInt>(),
                 )
                 )
@@ -1155,7 +1158,9 @@ impl Type {
                 Type::Value => BigInt::from(ns.value_length),
                 Type::Value => BigInt::from(ns.value_length),
                 Type::Uint(n) | Type::Int(n) => BigInt::from(n / 8),
                 Type::Uint(n) | Type::Int(n) => BigInt::from(n / 8),
                 Type::Rational => unreachable!(),
                 Type::Rational => unreachable!(),
-                Type::Array(_, dims) if dims.last().unwrap().is_none() => BigInt::from(4),
+                Type::Array(_, dims) if dims.last() == Some(&ArrayLength::Dynamic) => {
+                    BigInt::from(4)
+                }
                 Type::Array(ty, dims) => {
                 Type::Array(ty, dims) => {
                     let pointer_size = BigInt::from(4);
                     let pointer_size = BigInt::from(4);
                     if self.is_sparse_solana(ns) {
                     if self.is_sparse_solana(ns) {
@@ -1164,8 +1169,11 @@ impl Type {
                         ty.storage_slots(ns).mul(
                         ty.storage_slots(ns).mul(
                             dims.iter()
                             dims.iter()
                                 .map(|d| match d {
                                 .map(|d| match d {
-                                    None => &pointer_size,
-                                    Some(d) => d,
+                                    ArrayLength::Dynamic => &pointer_size,
+                                    ArrayLength::Fixed(d) => d,
+                                    ArrayLength::AnyFixed => {
+                                        panic!("unknown length");
+                                    }
                                 })
                                 })
                                 .product::<BigInt>(),
                                 .product::<BigInt>(),
                         )
                         )
@@ -1207,9 +1215,12 @@ impl Type {
                     ty.storage_slots(ns)
                     ty.storage_slots(ns)
                         * dims
                         * dims
                             .iter()
                             .iter()
-                            .map(|l| match l {
-                                None => &one,
-                                Some(l) => l,
+                            .map(|len| match len {
+                                ArrayLength::Dynamic => &one,
+                                ArrayLength::Fixed(len) => len,
+                                ArrayLength::AnyFixed => {
+                                    unreachable!("unknown length")
+                                }
                             })
                             })
                             .product::<BigInt>()
                             .product::<BigInt>()
                 }
                 }
@@ -1229,7 +1240,9 @@ impl Type {
                 Type::Value => BigInt::from(ns.value_length),
                 Type::Value => BigInt::from(ns.value_length),
                 Type::Uint(n) | Type::Int(n) => BigInt::from(n / 8),
                 Type::Uint(n) | Type::Int(n) => BigInt::from(n / 8),
                 Type::Rational => unreachable!(),
                 Type::Rational => unreachable!(),
-                Type::Array(_, dims) if dims.last().unwrap().is_none() => BigInt::from(4),
+                Type::Array(_, dims) if dims.last() == Some(&ArrayLength::Dynamic) => {
+                    BigInt::from(4)
+                }
                 Type::Array(ty, _) => {
                 Type::Array(ty, _) => {
                     if self.is_sparse_solana(ns) {
                     if self.is_sparse_solana(ns) {
                         BigInt::from(4)
                         BigInt::from(4)
@@ -1299,7 +1312,7 @@ impl Type {
             Type::String | Type::DynamicBytes => true,
             Type::String | Type::DynamicBytes => true,
             Type::Ref(r) => r.is_dynamic(ns),
             Type::Ref(r) => r.is_dynamic(ns),
             Type::Array(ty, dim) => {
             Type::Array(ty, dim) => {
-                if dim.iter().any(|d| d.is_none()) {
+                if dim.iter().any(|d| d == &ArrayLength::Dynamic) {
                     return true;
                     return true;
                 }
                 }
 
 
@@ -1334,7 +1347,7 @@ impl Type {
     pub fn is_dynamic_memory(&self) -> bool {
     pub fn is_dynamic_memory(&self) -> bool {
         match self {
         match self {
             Type::String | Type::DynamicBytes => true,
             Type::String | Type::DynamicBytes => true,
-            Type::Array(_, dim) if dim.last().unwrap().is_none() => true,
+            Type::Array(_, dim) if dim.last() == Some(&ArrayLength::Dynamic) => true,
             Type::Ref(ty) => ty.is_dynamic_memory(),
             Type::Ref(ty) => ty.is_dynamic_memory(),
             _ => false,
             _ => false,
         }
         }
@@ -1470,8 +1483,8 @@ impl Type {
                 ty.to_llvm_string(ns),
                 ty.to_llvm_string(ns),
                 len.iter()
                 len.iter()
                     .map(|r| match r {
                     .map(|r| match r {
-                        None => ":".to_string(),
-                        Some(r) => format!(":{}", r),
+                        ArrayLength::Dynamic | ArrayLength::AnyFixed => ":".to_string(),
+                        ArrayLength::Fixed(r) => format!(":{}", r),
                     })
                     })
                     .collect::<String>()
                     .collect::<String>()
             ),
             ),
@@ -1484,6 +1497,7 @@ impl Type {
             Type::Ref(r) => r.to_llvm_string(ns),
             Type::Ref(r) => r.to_llvm_string(ns),
             Type::StorageRef(_, r) => r.to_llvm_string(ns),
             Type::StorageRef(_, r) => r.to_llvm_string(ns),
             Type::UserType(no) => ns.user_types[*no].ty.to_llvm_string(ns),
             Type::UserType(no) => ns.user_types[*no].ty.to_llvm_string(ns),
+            Type::Slice(ty) => format!("slice:{}", ty.to_llvm_string(ns)),
             _ => unreachable!(),
             _ => unreachable!(),
         }
         }
     }
     }
@@ -1492,14 +1506,14 @@ impl Type {
     pub fn is_sparse_solana(&self, ns: &Namespace) -> bool {
     pub fn is_sparse_solana(&self, ns: &Namespace) -> bool {
         match self.deref_any() {
         match self.deref_any() {
             Type::Mapping(..) => true,
             Type::Mapping(..) => true,
-            Type::Array(_, dims) if dims.last().unwrap().is_none() => false,
+            Type::Array(_, dims) if dims.last() == Some(&ArrayLength::Dynamic) => false,
             Type::Array(ty, dims) => {
             Type::Array(ty, dims) => {
                 let pointer_size = BigInt::from(4);
                 let pointer_size = BigInt::from(4);
                 let len = ty.storage_slots(ns).mul(
                 let len = ty.storage_slots(ns).mul(
                     dims.iter()
                     dims.iter()
                         .map(|d| match d {
                         .map(|d| match d {
-                            None => &pointer_size,
-                            Some(d) => d,
+                            ArrayLength::Fixed(d) => d,
+                            _ => &pointer_size,
                         })
                         })
                         .product::<BigInt>(),
                         .product::<BigInt>(),
                 );
                 );

+ 7 - 4
src/sema/yul/expression.rs

@@ -1,4 +1,4 @@
-use crate::ast::{Namespace, Parameter, Symbol, Type};
+use crate::ast::{ArrayLength, Namespace, Parameter, Symbol, Type};
 use crate::sema::diagnostics::Diagnostics;
 use crate::sema::diagnostics::Diagnostics;
 use crate::sema::expression::{unescape, ExprContext};
 use crate::sema::expression::{unescape, ExprContext};
 use crate::sema::symtable::{Symtable, VariableUsage};
 use crate::sema::symtable::{Symtable, VariableUsage};
@@ -562,13 +562,16 @@ fn resolve_suffix_access(
             Some(StorageLocation::Calldata(_)),
             Some(StorageLocation::Calldata(_)),
             _,
             _,
         ) => {
         ) => {
-            if dims.last().unwrap().is_none() && id.name != "offset" && id.name != "length" {
+            if dims.last() == Some(&ArrayLength::Dynamic)
+                && id.name != "offset"
+                && id.name != "length"
+            {
                 ns.diagnostics.push(Diagnostic::error(
                 ns.diagnostics.push(Diagnostic::error(
                     resolved_expr.loc(),
                     resolved_expr.loc(),
                     "calldata variables only support '.offset' and '.length'".to_string(),
                     "calldata variables only support '.offset' and '.length'".to_string(),
                 ));
                 ));
                 return Err(());
                 return Err(());
-            } else if dims.last().unwrap().is_some() {
+            } else if matches!(dims.last(), Some(ArrayLength::Fixed(_))) {
                 ns.diagnostics.push(Diagnostic::error(
                 ns.diagnostics.push(Diagnostic::error(
                     resolved_expr.loc(),
                     resolved_expr.loc(),
                     format!(
                     format!(
@@ -769,7 +772,7 @@ pub(crate) fn check_type(
             Some(StorageLocation::Calldata(_)),
             Some(StorageLocation::Calldata(_)),
             ..,
             ..,
         ) => {
         ) => {
-            if dims.last().unwrap().is_none() {
+            if dims.last() == Some(&ArrayLength::Dynamic) {
                 return Some(Diagnostic::error(
                 return Some(Diagnostic::error(
                     expr.loc(),
                     expr.loc(),
                     "Calldata arrays must be accessed with '.offset', '.length' and the 'calldatacopy' function".to_string()
                     "Calldata arrays must be accessed with '.offset', '.length' and the 'calldatacopy' function".to_string()

+ 2 - 2
src/sema/yul/tests/expression.rs

@@ -1,6 +1,6 @@
 #![cfg(test)]
 #![cfg(test)]
 
 
-use crate::ast::{Namespace, Parameter, Symbol, Type, Variable};
+use crate::ast::{ArrayLength, Namespace, Parameter, Symbol, Type, Variable};
 use crate::diagnostics::Diagnostics;
 use crate::diagnostics::Diagnostics;
 use crate::sema::expression::ExprContext;
 use crate::sema::expression::ExprContext;
 use crate::sema::symtable::{Symtable, VariableInitializer, VariableUsage};
 use crate::sema::symtable::{Symtable, VariableInitializer, VariableUsage};
@@ -986,7 +986,7 @@ fn test_check_types() {
 
 
     let expr = YulExpression::SolidityLocalVariable(
     let expr = YulExpression::SolidityLocalVariable(
         loc,
         loc,
-        Type::Array(Box::new(Type::Int(8)), vec![None]),
+        Type::Array(Box::new(Type::Int(8)), vec![ArrayLength::Dynamic]),
         Some(StorageLocation::Calldata(loc)),
         Some(StorageLocation::Calldata(loc)),
         0,
         0,
     );
     );

+ 4 - 4
tests/codegen_testcases/solidity/slice1.sol

@@ -3,8 +3,8 @@ contract c {
 // BEGIN-CHECK: c::function::test1
 // BEGIN-CHECK: c::function::test1
 	function test1() public pure{
 	function test1() public pure{
 		bytes x = "foo1";
 		bytes x = "foo1";
-		// x is not being used, so it can be a slice
-// CHECK: alloc slice uint32 4 "foo1"
+		// x is not being used, so it can be a bytes1 slice
+// CHECK: alloc bytes1 slice uint32 4 "foo1"
 	bytes y = x;
 	bytes y = x;
 	}
 	}
 
 
@@ -27,7 +27,7 @@ contract c {
 		bytes x = "foo3";
 		bytes x = "foo3";
 
 
 		foo(x);
 		foo(x);
-		// no slices for function arguments yet, so it must be a vector
+		// no bytes1 slices for function arguments yet, so it must be a vector
 // CHECK: alloc bytes uint32 4 "foo3"
 // CHECK: alloc bytes uint32 4 "foo3"
 	}
 	}
 
 
@@ -44,7 +44,7 @@ contract c {
 		string y = x + "if";
 		string y = x + "if";
 
 
 		print(x);
 		print(x);
-// CHECK: alloc slice uint32 4 "foo4"
+// CHECK: alloc bytes1 slice uint32 4 "foo4"
 	}
 	}
 
 
 // BEGIN-CHECK: c::function::test5
 // BEGIN-CHECK: c::function::test5

+ 2 - 2
tests/contract_testcases/ewasm/public_internal_function.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/ewasm/public_internal_function.sol" {
 	A [label="name:A\ncontract: foo\ntests/contract_testcases/ewasm/public_internal_function.sol:2:12-13\nfield name:a ty:function() internal"]
 	A [label="name:A\ncontract: foo\ntests/contract_testcases/ewasm/public_internal_function.sol:2:12-13\nfield name:a ty:function() internal"]
 	contract [label="contract foo\ntests/contract_testcases/ewasm/public_internal_function.sol:1:1-7:2"]
 	contract [label="contract foo\ntests/contract_testcases/ewasm/public_internal_function.sol:1:1-7:2"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/ewasm/public_internal_function.sol:1:1-7:2"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/ewasm/public_internal_function.sol:1:1-7:2"]
-	diagnostic_7 [label="variable of type internal function cannot be 'public'\nlevel Error\ntests/contract_testcases/ewasm/public_internal_function.sol:6:5-8"]
+	diagnostic_6 [label="variable of type internal function cannot be 'public'\nlevel Error\ntests/contract_testcases/ewasm/public_internal_function.sol:6:5-8"]
 	structs -> A
 	structs -> A
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

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

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/solana/comment.sol" {
 strict digraph "tests/contract_testcases/solana/comment.sol" {
 	contract [label="contract Hello\ntests/contract_testcases/solana/comment.sol:1:24-4:2"]
 	contract [label="contract Hello\ntests/contract_testcases/solana/comment.sol:1:24-4:2"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/solana/comment.sol:1:1-23"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/solana/comment.sol:1:1-23"]
-	diagnostic_6 [label="found contract 'Hello'\nlevel Debug\ntests/contract_testcases/solana/comment.sol:1:24-4:2"]
+	diagnostic_5 [label="found contract 'Hello'\nlevel Debug\ntests/contract_testcases/solana/comment.sol:1:24-4:2"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Debug"]
+	diagnostics -> diagnostic_5 [label="Debug"]
 }
 }

+ 5 - 5
tests/contract_testcases/solana/create_contract/base_contract.dot

@@ -2,15 +2,15 @@ strict digraph "tests/contract_testcases/solana/create_contract/base_contract.so
 	MathError [label="name: MathError\ncontract: Math\ntests/contract_testcases/solana/create_contract/base_contract.sol:3:13-5:14\nvalue: NO_ERROR"]
 	MathError [label="name: MathError\ncontract: Math\ntests/contract_testcases/solana/create_contract/base_contract.sol:3:13-5:14\nvalue: NO_ERROR"]
 	WithMath [label="name:WithMath\ncontract: IsMath\ntests/contract_testcases/solana/create_contract/base_contract.sol:9:20-28\nfield name:math ty:enum Math.MathError"]
 	WithMath [label="name:WithMath\ncontract: IsMath\ntests/contract_testcases/solana/create_contract/base_contract.sol:9:20-28\nfield name:math ty:enum Math.MathError"]
 	contract [label="contract Math\ntests/contract_testcases/solana/create_contract/base_contract.sol:2:9-6:10"]
 	contract [label="contract Math\ntests/contract_testcases/solana/create_contract/base_contract.sol:2:9-6:10"]
-	contract_7 [label="contract IsMath\ntests/contract_testcases/solana/create_contract/base_contract.sol:8:9-12:10"]
+	contract_6 [label="contract IsMath\ntests/contract_testcases/solana/create_contract/base_contract.sol:8:9-12:10"]
 	base [label="base Math\ntests/contract_testcases/solana/create_contract/base_contract.sol:8:28-32"]
 	base [label="base Math\ntests/contract_testcases/solana/create_contract/base_contract.sol:8:28-32"]
 	diagnostic [label="found contract 'Math'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract.sol:2:9-6:10"]
 	diagnostic [label="found contract 'Math'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract.sol:2:9-6:10"]
-	diagnostic_11 [label="found contract 'IsMath'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract.sol:8:9-12:10"]
+	diagnostic_10 [label="found contract 'IsMath'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract.sol:8:9-12:10"]
 	enums -> MathError
 	enums -> MathError
 	structs -> WithMath
 	structs -> WithMath
 	contracts -> contract
 	contracts -> contract
-	contracts -> contract_7
-	contract_7 -> base [label="base"]
+	contracts -> contract_6
+	contract_6 -> base [label="base"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_11 [label="Debug"]
+	diagnostics -> diagnostic_10 [label="Debug"]
 }
 }

+ 10 - 10
tests/contract_testcases/solana/create_contract/base_contract_01.dot

@@ -3,22 +3,22 @@ strict digraph "tests/contract_testcases/solana/create_contract/base_contract_01
 	MathError [label="name: MathError\ncontract: Math\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:8:13-10:14\nvalue: NO_ERROR"]
 	MathError [label="name: MathError\ncontract: Math\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:8:13-10:14\nvalue: NO_ERROR"]
 	WithMath [label="name:WithMath\ncontract: IsMath\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:14:20-28\nfield name:math ty:enum Math.MathError\nfield name:logic ty:enum Logic.LogicError"]
 	WithMath [label="name:WithMath\ncontract: IsMath\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:14:20-28\nfield name:math ty:enum Math.MathError\nfield name:logic ty:enum Logic.LogicError"]
 	contract [label="contract Logic\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:2:9-6:10"]
 	contract [label="contract Logic\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:2:9-6:10"]
-	contract_8 [label="contract Math\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:7:9-11:10"]
+	contract_7 [label="contract Math\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:7:9-11:10"]
 	base [label="base Logic\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:7:26-31"]
 	base [label="base Logic\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:7:26-31"]
-	contract_10 [label="contract IsMath\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:13:9-18:10"]
-	base_11 [label="base Math\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:13:28-32"]
+	contract_9 [label="contract IsMath\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:13:9-18:10"]
+	base_10 [label="base Math\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:13:28-32"]
 	diagnostic [label="found contract 'Logic'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:2:9-6:10"]
 	diagnostic [label="found contract 'Logic'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:2:9-6:10"]
-	diagnostic_14 [label="found contract 'Math'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:7:9-11:10"]
-	diagnostic_15 [label="found contract 'IsMath'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:13:9-18:10"]
+	diagnostic_13 [label="found contract 'Math'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:7:9-11:10"]
+	diagnostic_14 [label="found contract 'IsMath'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_01.sol:13:9-18:10"]
 	enums -> LogicError
 	enums -> LogicError
 	enums -> MathError
 	enums -> MathError
 	structs -> WithMath
 	structs -> WithMath
 	contracts -> contract
 	contracts -> contract
-	contracts -> contract_8
-	contract_8 -> base [label="base"]
-	contracts -> contract_10
-	contract_10 -> base_11 [label="base"]
+	contracts -> contract_7
+	contract_7 -> base [label="base"]
+	contracts -> contract_9
+	contract_9 -> base_10 [label="base"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_13 [label="Debug"]
 	diagnostics -> diagnostic_14 [label="Debug"]
 	diagnostics -> diagnostic_14 [label="Debug"]
-	diagnostics -> diagnostic_15 [label="Debug"]
 }
 }

+ 10 - 10
tests/contract_testcases/solana/create_contract/base_contract_02.dot

@@ -2,21 +2,21 @@ strict digraph "tests/contract_testcases/solana/create_contract/base_contract_02
 	LogicFields [label="name:LogicFields\ncontract: Logic\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:3:20-31\nfield name:logia ty:uint256"]
 	LogicFields [label="name:LogicFields\ncontract: Logic\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:3:20-31\nfield name:logia ty:uint256"]
 	WithMath [label="name:WithMath\ncontract: IsMath\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:11:20-28\nfield name:logia ty:struct Logic.LogicFields"]
 	WithMath [label="name:WithMath\ncontract: IsMath\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:11:20-28\nfield name:logia ty:struct Logic.LogicFields"]
 	contract [label="contract Logic\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:2:9-6:10"]
 	contract [label="contract Logic\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:2:9-6:10"]
-	contract_6 [label="contract Math\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:7:9-8:10"]
+	contract_5 [label="contract Math\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:7:9-8:10"]
 	base [label="base Logic\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:7:26-31"]
 	base [label="base Logic\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:7:26-31"]
-	contract_8 [label="contract IsMath\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:10:9-14:10"]
-	base_9 [label="base Math\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:10:28-32"]
+	contract_7 [label="contract IsMath\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:10:9-14:10"]
+	base_8 [label="base Math\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:10:28-32"]
 	diagnostic [label="found contract 'Logic'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:2:9-6:10"]
 	diagnostic [label="found contract 'Logic'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:2:9-6:10"]
-	diagnostic_12 [label="found contract 'Math'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:7:9-8:10"]
-	diagnostic_13 [label="found contract 'IsMath'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:10:9-14:10"]
+	diagnostic_11 [label="found contract 'Math'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:7:9-8:10"]
+	diagnostic_12 [label="found contract 'IsMath'\nlevel Debug\ntests/contract_testcases/solana/create_contract/base_contract_02.sol:10:9-14:10"]
 	structs -> LogicFields
 	structs -> LogicFields
 	structs -> WithMath
 	structs -> WithMath
 	contracts -> contract
 	contracts -> contract
-	contracts -> contract_6
-	contract_6 -> base [label="base"]
-	contracts -> contract_8
-	contract_8 -> base_9 [label="base"]
+	contracts -> contract_5
+	contract_5 -> base [label="base"]
+	contracts -> contract_7
+	contract_7 -> base_8 [label="base"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_11 [label="Debug"]
 	diagnostics -> diagnostic_12 [label="Debug"]
 	diagnostics -> diagnostic_12 [label="Debug"]
-	diagnostics -> diagnostic_13 [label="Debug"]
 }
 }

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

@@ -1,16 +1,26 @@
 strict digraph "tests/contract_testcases/solana/expressions/selector_in_free_function.sol" {
 strict digraph "tests/contract_testcases/solana/expressions/selector_in_free_function.sol" {
+	x [label="function x\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:6:9-38\nsignature x()\nvisibility internal\nmutability nonpayable"]
+	returns [label="returns\nbytes4 "]
+	return [label="return\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:7:13-32"]
+	builtins [label="builtin FunctionSelector\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:7:20-23"]
+	internal_function [label="function(bytes) internal returns (void)\nI.X\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:7:20-21"]
 	contract [label="contract I\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:2:9-4:10"]
 	contract [label="contract I\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:2:9-4:10"]
 	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"]
 	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 "]
 	parameters [label="parameters\nbytes "]
-	contract_5 [label="contract foo\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-24"]
+	contract_11 [label="contract foo\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-24"]
 	diagnostic [label="found interface 'I'\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:2:9-4:10"]
 	diagnostic [label="found interface 'I'\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:2:9-4:10"]
-	diagnostic_8 [label="function can be declared 'pure'\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:6:9-38"]
-	diagnostic_9 [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-24"]
+	diagnostic_14 [label="function can be declared 'pure'\nlevel Warning\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:6:9-38"]
+	diagnostic_15 [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/solana/expressions/selector_in_free_function.sol:10:9-24"]
+	free_functions -> x [label="function"]
+	x -> returns [label="returns"]
+	x -> return [label="body"]
+	return -> builtins [label="expr"]
+	builtins -> internal_function [label="arg #0"]
 	contracts -> contract
 	contracts -> contract
 	contract -> X [label="function"]
 	contract -> X [label="function"]
 	X -> parameters [label="parameters"]
 	X -> parameters [label="parameters"]
-	contracts -> contract_5
+	contracts -> contract_11
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Warning"]
-	diagnostics -> diagnostic_9 [label="Debug"]
+	diagnostics -> diagnostic_14 [label="Warning"]
+	diagnostics -> diagnostic_15 [label="Debug"]
 }
 }

+ 4 - 4
tests/contract_testcases/solana/immutable_function.dot

@@ -1,10 +1,10 @@
 strict digraph "tests/contract_testcases/solana/immutable_function.sol" {
 strict digraph "tests/contract_testcases/solana/immutable_function.sol" {
 	contract [label="contract t\ntests/contract_testcases/solana/immutable_function.sol:1:26-4:2"]
 	contract [label="contract t\ntests/contract_testcases/solana/immutable_function.sol:1:26-4:2"]
 	diagnostic [label="function cannot be declared 'immutable'\nlevel Error\ntests/contract_testcases/solana/immutable_function.sol:1:14-23"]
 	diagnostic [label="function cannot be declared 'immutable'\nlevel Error\ntests/contract_testcases/solana/immutable_function.sol:1:14-23"]
-	diagnostic_6 [label="found contract 't'\nlevel Debug\ntests/contract_testcases/solana/immutable_function.sol:1:26-4:2"]
-	diagnostic_7 [label="function cannot be declared 'immutable'\nlevel Error\ntests/contract_testcases/solana/immutable_function.sol:3:18-27"]
+	diagnostic_5 [label="found contract 't'\nlevel Debug\ntests/contract_testcases/solana/immutable_function.sol:1:26-4:2"]
+	diagnostic_6 [label="function cannot be declared 'immutable'\nlevel Error\ntests/contract_testcases/solana/immutable_function.sol:3:18-27"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Error"]
 	diagnostics -> diagnostic [label="Error"]
-	diagnostics -> diagnostic_6 [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_5 [label="Debug"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 36 - 14
tests/contract_testcases/solana/import_contracts_via_object.dot

@@ -1,28 +1,50 @@
 strict digraph "tests/contract_testcases/solana/import_contracts_via_object.sol" {
 strict digraph "tests/contract_testcases/solana/import_contracts_via_object.sol" {
 	S [label="name:S\ntests/contract_testcases/solana/simple.sol:3:8-9\nfield name:f1 ty:int64\nfield name:f2 ty:bool"]
 	S [label="name:S\ntests/contract_testcases/solana/simple.sol:3:8-9\nfield name:f1 ty:int64\nfield name:f2 ty:bool"]
+	inc [label="function inc\ntests/contract_testcases/solana/simple.sol:6:2-7:23\nsignature inc((int64,bool))\nvisibility internal\nmutability pure"]
+	parameters [label="parameters\nstruct S s"]
+	expr [label="expression\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	assign [label="assign\nvoid\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	structmember [label="struct member #0 int64\ntests/contract_testcases/solana/simple.sol:7:28-30"]
+	variable [label="variable: s\nstruct S\ntests/contract_testcases/solana/simple.sol:7:26-27"]
+	add [label="add\nint64\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	load [label="load int64\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	structmember_11 [label="struct member #0 int64\ntests/contract_testcases/solana/simple.sol:7:28-30"]
+	variable_12 [label="variable: s\nstruct S\ntests/contract_testcases/solana/simple.sol:7:26-27"]
+	number_literal [label="int64 literal: 1\ntests/contract_testcases/solana/simple.sol:7:34-35"]
 	contract [label="contract C\ntests/contract_testcases/solana/import_contracts_via_object.sol:2:1-11:2"]
 	contract [label="contract C\ntests/contract_testcases/solana/import_contracts_via_object.sol:2:1-11:2"]
 	base [label="base A\ntests/contract_testcases/solana/import_contracts_via_object.sol:3:15-20"]
 	base [label="base A\ntests/contract_testcases/solana/import_contracts_via_object.sol:3:15-20"]
 	using [label="library L"]
 	using [label="library L"]
-	node_6 [label="constructor \ncontract: C\ntests/contract_testcases/solana/import_contracts_via_object.sol:5:2-23\nsignature ()\nvisibility public\nmutability nonpayable"]
+	node_18 [label="constructor \ncontract: C\ntests/contract_testcases/solana/import_contracts_via_object.sol:5:2-23\nsignature ()\nvisibility public\nmutability nonpayable"]
 	foo [label="function foo\ncontract: C\ntests/contract_testcases/solana/import_contracts_via_object.sol:8:2-23\nsignature foo()\nvisibility public\nmutability nonpayable"]
 	foo [label="function foo\ncontract: C\ntests/contract_testcases/solana/import_contracts_via_object.sol:8:2-23\nsignature foo()\nvisibility public\nmutability nonpayable"]
-	contract_8 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-14"]
-	contract_9 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
+	contract_20 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-14"]
+	contract_21 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
 	diagnostic [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/import_contracts_via_object.sol:2:1-11:2"]
 	diagnostic [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/import_contracts_via_object.sol:2:1-11:2"]
-	diagnostic_12 [label="revert with custom error 'IMP.E' not supported yet\nlevel Error\ntests/contract_testcases/solana/import_contracts_via_object.sol:6:10-15"]
-	diagnostic_13 [label="revert with custom errors or named arguments not supported yet\nlevel Error\ntests/contract_testcases/solana/import_contracts_via_object.sol:9:3-25"]
-	diagnostic_14 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:1-14"]
-	diagnostic_15 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
+	diagnostic_24 [label="revert with custom error 'IMP.E' not supported yet\nlevel Error\ntests/contract_testcases/solana/import_contracts_via_object.sol:6:10-15"]
+	diagnostic_25 [label="revert with custom errors or named arguments not supported yet\nlevel Error\ntests/contract_testcases/solana/import_contracts_via_object.sol:9:3-25"]
+	diagnostic_26 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:1-14"]
+	diagnostic_27 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
 	structs -> S
 	structs -> S
+	free_functions -> inc [label="function"]
+	inc -> parameters [label="parameters"]
+	inc -> expr [label="body"]
+	expr -> assign [label="expr"]
+	assign -> structmember [label="left"]
+	structmember -> variable [label="var"]
+	assign -> add [label="right"]
+	add -> load [label="left"]
+	load -> structmember_11 [label="expr"]
+	structmember_11 -> variable_12 [label="var"]
+	add -> number_literal [label="right"]
 	contracts -> contract
 	contracts -> contract
 	contract -> base [label="base"]
 	contract -> base [label="base"]
 	contract -> using [label="base"]
 	contract -> using [label="base"]
-	contract -> node_6 [label="constructor"]
+	contract -> node_18 [label="constructor"]
 	contract -> foo [label="function"]
 	contract -> foo [label="function"]
-	contracts -> contract_8
-	contracts -> contract_9
+	contracts -> contract_20
+	contracts -> contract_21
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_12 [label="Error"]
-	diagnostics -> diagnostic_13 [label="Error"]
-	diagnostics -> diagnostic_14 [label="Debug"]
-	diagnostics -> diagnostic_15 [label="Debug"]
+	diagnostics -> diagnostic_24 [label="Error"]
+	diagnostics -> diagnostic_25 [label="Error"]
+	diagnostics -> diagnostic_26 [label="Debug"]
+	diagnostics -> diagnostic_27 [label="Debug"]
 }
 }

+ 54 - 36
tests/contract_testcases/solana/keep_on_resolving.dot

@@ -4,59 +4,77 @@ strict digraph "tests/contract_testcases/solana/keep_on_resolving.sol" {
 	GlobalFoo [label="name:GlobalFoo\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:7:9-18\nfield name:f1 ty:int256"]
 	GlobalFoo [label="name:GlobalFoo\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:7:9-18\nfield name:f1 ty:int256"]
 	GlobalFoo_5 [label="name:GlobalFoo ty:address payable\ntests/contract_testcases/solana/type_decl_broken.sol:1:1-34"]
 	GlobalFoo_5 [label="name:GlobalFoo ty:address payable\ntests/contract_testcases/solana/type_decl_broken.sol:1:1-34"]
 	Value [label="name:Value ty:uint128\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:9:2-23"]
 	Value [label="name:Value ty:uint128\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:9:2-23"]
+	f [label="function f\ntests/contract_testcases/solana/keep_on_resolving.sol:6:1-7:30\nsignature f((unresolved))\nvisibility internal\nmutability nonpayable"]
+	parameters [label="parameters\nstruct S s"]
+	returns [label="returns\nint256 "]
+	return [label="return\ntests/contract_testcases/solana/keep_on_resolving.sol:8:2-13"]
+	load [label="load unresolved\ntests/contract_testcases/solana/keep_on_resolving.sol:8:2-13"]
+	structmember [label="struct member #0 unresolved\ntests/contract_testcases/solana/keep_on_resolving.sol:8:11-13"]
+	variable [label="variable: s\nstruct S\ntests/contract_testcases/solana/keep_on_resolving.sol:8:9-10"]
+	g [label="function g\ntests/contract_testcases/solana/keep_on_resolving.sol:10:1-11:17\nsignature g((unresolved))\nvisibility internal\nmutability nonpayable"]
+	parameters_16 [label="parameters\nstruct S s"]
 	contract [label="contract c\ntests/contract_testcases/solana/type_decl_broken.sol:2:1-19:2"]
 	contract [label="contract c\ntests/contract_testcases/solana/type_decl_broken.sol:2:1-19:2"]
 	inc_and_wrap [label="function inc_and_wrap\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:12:2-56\nsignature inc_and_wrap(int128)\nvisibility public\nmutability nonpayable"]
 	inc_and_wrap [label="function inc_and_wrap\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:12:2-56\nsignature inc_and_wrap(int128)\nvisibility public\nmutability nonpayable"]
-	parameters [label="parameters\nint128 v"]
-	returns [label="returns\nusertype c.Value "]
+	parameters_20 [label="parameters\nint128 v"]
+	returns_21 [label="returns\nusertype c.Value "]
 	dec_and_unwrap [label="function dec_and_unwrap\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:16:2-59\nsignature dec_and_unwrap(uint128)\nvisibility public\nmutability nonpayable"]
 	dec_and_unwrap [label="function dec_and_unwrap\ncontract: c\ntests/contract_testcases/solana/type_decl_broken.sol:16:2-59\nsignature dec_and_unwrap(uint128)\nvisibility public\nmutability nonpayable"]
-	parameters_13 [label="parameters\nusertype c.Value v"]
-	returns_14 [label="returns\nuint128 "]
-	return [label="return\ntests/contract_testcases/solana/type_decl_broken.sol:17:3-29"]
+	parameters_23 [label="parameters\nusertype c.Value v"]
+	returns_24 [label="returns\nuint128 "]
+	return_25 [label="return\ntests/contract_testcases/solana/type_decl_broken.sol:17:3-29"]
 	subtract [label="subtract\nuint128\ntests/contract_testcases/solana/type_decl_broken.sol:17:10-29"]
 	subtract [label="subtract\nuint128\ntests/contract_testcases/solana/type_decl_broken.sol:17:10-29"]
 	builtins [label="builtin UserTypeUnwrap\ntests/contract_testcases/solana/type_decl_broken.sol:17:10-25"]
 	builtins [label="builtin UserTypeUnwrap\ntests/contract_testcases/solana/type_decl_broken.sol:17:10-25"]
-	variable [label="variable: v\nusertype c.Value\ntests/contract_testcases/solana/type_decl_broken.sol:17:23-24"]
+	variable_28 [label="variable: v\nusertype c.Value\ntests/contract_testcases/solana/type_decl_broken.sol:17:23-24"]
 	number_literal [label="uint128 literal: 1\ntests/contract_testcases/solana/type_decl_broken.sol:17:28-29"]
 	number_literal [label="uint128 literal: 1\ntests/contract_testcases/solana/type_decl_broken.sol:17:28-29"]
 	diagnostic [label="type 'in' not found\nlevel Error\ntests/contract_testcases/solana/keep_on_resolving.sol:4:2-4"]
 	diagnostic [label="type 'in' not found\nlevel Error\ntests/contract_testcases/solana/keep_on_resolving.sol:4:2-4"]
-	diagnostic_22 [label="expected 'struct S', found integer\nlevel Error\ntests/contract_testcases/solana/keep_on_resolving.sol:15:6-7"]
-	diagnostic_23 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/type_decl_broken.sol:2:1-19:2"]
-	diagnostic_24 [label="foo is already defined as a struct\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:5:7-10"]
+	diagnostic_32 [label="expected 'struct S', found integer\nlevel Error\ntests/contract_testcases/solana/keep_on_resolving.sol:15:6-7"]
+	diagnostic_33 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/type_decl_broken.sol:2:1-19:2"]
+	diagnostic_34 [label="foo is already defined as a struct\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:5:7-10"]
 	note [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:4:9-12"]
 	note [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:4:9-12"]
-	diagnostic_26 [label="'int256[2]' is not an elementary value type\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:5:14-20"]
-	diagnostic_27 [label="foo is already defined as a struct\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:6:7-10"]
-	note_28 [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:4:9-12"]
-	diagnostic_29 [label="GlobalFoo is already defined as an user type\nlevel Warning\ntests/contract_testcases/solana/type_decl_broken.sol:7:9-18"]
-	note_30 [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:1:6-15"]
-	diagnostic_31 [label="Value is already defined as an user type\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:10:9-14"]
-	note_32 [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:9:7-12"]
-	diagnostic_33 [label="implicit conversion would change sign from int136 to uint128\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:13:21-26"]
+	diagnostic_36 [label="'int256[2]' is not an elementary value type\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:5:14-20"]
+	diagnostic_37 [label="foo is already defined as a struct\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:6:7-10"]
+	note_38 [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:4:9-12"]
+	diagnostic_39 [label="GlobalFoo is already defined as an user type\nlevel Warning\ntests/contract_testcases/solana/type_decl_broken.sol:7:9-18"]
+	note_40 [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:1:6-15"]
+	diagnostic_41 [label="Value is already defined as an user type\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:10:9-14"]
+	note_42 [label="location of previous definition\ntests/contract_testcases/solana/type_decl_broken.sol:9:7-12"]
+	diagnostic_43 [label="implicit conversion would change sign from int136 to uint128\nlevel Error\ntests/contract_testcases/solana/type_decl_broken.sol:13:21-26"]
 	structs -> S
 	structs -> S
 	structs -> foo
 	structs -> foo
 	structs -> GlobalFoo
 	structs -> GlobalFoo
 	types -> GlobalFoo_5
 	types -> GlobalFoo_5
 	types -> Value
 	types -> Value
+	free_functions -> f [label="function"]
+	f -> parameters [label="parameters"]
+	f -> returns [label="returns"]
+	f -> return [label="body"]
+	return -> load [label="expr"]
+	load -> structmember [label="expr"]
+	structmember -> variable [label="var"]
+	free_functions -> g [label="function"]
+	g -> parameters_16 [label="parameters"]
 	contracts -> contract
 	contracts -> contract
 	contract -> inc_and_wrap [label="function"]
 	contract -> inc_and_wrap [label="function"]
-	inc_and_wrap -> parameters [label="parameters"]
-	inc_and_wrap -> returns [label="returns"]
+	inc_and_wrap -> parameters_20 [label="parameters"]
+	inc_and_wrap -> returns_21 [label="returns"]
 	contract -> dec_and_unwrap [label="function"]
 	contract -> dec_and_unwrap [label="function"]
-	dec_and_unwrap -> parameters_13 [label="parameters"]
-	dec_and_unwrap -> returns_14 [label="returns"]
-	dec_and_unwrap -> return [label="body"]
-	return -> subtract [label="expr"]
+	dec_and_unwrap -> parameters_23 [label="parameters"]
+	dec_and_unwrap -> returns_24 [label="returns"]
+	dec_and_unwrap -> return_25 [label="body"]
+	return_25 -> subtract [label="expr"]
 	subtract -> builtins [label="left"]
 	subtract -> builtins [label="left"]
-	builtins -> variable [label="arg #0"]
+	builtins -> variable_28 [label="arg #0"]
 	subtract -> number_literal [label="right"]
 	subtract -> number_literal [label="right"]
 	diagnostics -> diagnostic [label="Error"]
 	diagnostics -> diagnostic [label="Error"]
-	diagnostics -> diagnostic_22 [label="Error"]
-	diagnostics -> diagnostic_23 [label="Debug"]
-	diagnostics -> diagnostic_24 [label="Error"]
-	diagnostic_24 -> note [label="note"]
-	diagnostics -> diagnostic_26 [label="Error"]
-	diagnostics -> diagnostic_27 [label="Error"]
-	diagnostic_27 -> note_28 [label="note"]
-	diagnostics -> diagnostic_29 [label="Warning"]
-	diagnostic_29 -> note_30 [label="note"]
-	diagnostics -> diagnostic_31 [label="Error"]
-	diagnostic_31 -> note_32 [label="note"]
-	diagnostics -> diagnostic_33 [label="Error"]
+	diagnostics -> diagnostic_32 [label="Error"]
+	diagnostics -> diagnostic_33 [label="Debug"]
+	diagnostics -> diagnostic_34 [label="Error"]
+	diagnostic_34 -> note [label="note"]
+	diagnostics -> diagnostic_36 [label="Error"]
+	diagnostics -> diagnostic_37 [label="Error"]
+	diagnostic_37 -> note_38 [label="note"]
+	diagnostics -> diagnostic_39 [label="Warning"]
+	diagnostic_39 -> note_40 [label="note"]
+	diagnostics -> diagnostic_41 [label="Error"]
+	diagnostic_41 -> note_42 [label="note"]
+	diagnostics -> diagnostic_43 [label="Error"]
 }
 }

+ 122 - 100
tests/contract_testcases/solana/override.dot

@@ -1,5 +1,16 @@
 strict digraph "tests/contract_testcases/solana/override.sol" {
 strict digraph "tests/contract_testcases/solana/override.sol" {
 	S [label="name:S\ntests/contract_testcases/solana/simple.sol:3:8-9\nfield name:f1 ty:int64\nfield name:f2 ty:bool"]
 	S [label="name:S\ntests/contract_testcases/solana/simple.sol:3:8-9\nfield name:f1 ty:int64\nfield name:f2 ty:bool"]
+	inc [label="function inc\ntests/contract_testcases/solana/simple.sol:6:2-7:23\nsignature inc((int64,bool))\nvisibility internal\nmutability pure"]
+	parameters [label="parameters\nstruct S s"]
+	expr [label="expression\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	assign [label="assign\nvoid\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	structmember [label="struct member #0 int64\ntests/contract_testcases/solana/simple.sol:7:28-30"]
+	variable [label="variable: s\nstruct S\ntests/contract_testcases/solana/simple.sol:7:26-27"]
+	add [label="add\nint64\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	load [label="load int64\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	structmember_11 [label="struct member #0 int64\ntests/contract_testcases/solana/simple.sol:7:28-30"]
+	variable_12 [label="variable: s\nstruct S\ntests/contract_testcases/solana/simple.sol:7:26-27"]
+	number_literal [label="int64 literal: 1\ntests/contract_testcases/solana/simple.sol:7:34-35"]
 	contract [label="contract C\ntests/contract_testcases/solana/override.sol:4:1-7:2"]
 	contract [label="contract C\ntests/contract_testcases/solana/override.sol:4:1-7:2"]
 	base [label="base A\ntests/contract_testcases/solana/override.sol:5:15-20"]
 	base [label="base A\ntests/contract_testcases/solana/override.sol:5:15-20"]
 	var [label="variable meh\nvisibility public\ntests/contract_testcases/solana/override.sol:6:2-32"]
 	var [label="variable meh\nvisibility public\ntests/contract_testcases/solana/override.sol:6:2-32"]
@@ -8,61 +19,72 @@ strict digraph "tests/contract_testcases/solana/override.sol" {
 	return [label="return\nimplicit"]
 	return [label="return\nimplicit"]
 	storage_load [label="storage load int256\nimplicit"]
 	storage_load [label="storage load int256\nimplicit"]
 	storage_var [label="storage variable\nC.meh\nint256 storage\nimplicit"]
 	storage_var [label="storage variable\nC.meh\nint256 storage\nimplicit"]
-	contract_11 [label="contract A\ntests/contract_testcases/solana/override.sol:8:1-11:2"]
+	contract_23 [label="contract A\ntests/contract_testcases/solana/override.sol:8:1-11:2"]
 	foo [label="function foo\ncontract: A\ntests/contract_testcases/solana/override.sol:10:5-43\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
 	foo [label="function foo\ncontract: A\ntests/contract_testcases/solana/override.sol:10:5-43\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
-	returns_13 [label="returns\nuint256 "]
-	contract_14 [label="contract B\ntests/contract_testcases/solana/override.sol:11:2-14:2"]
-	foo_15 [label="function foo\ncontract: B\ntests/contract_testcases/solana/override.sol:13:5-43\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
-	returns_16 [label="returns\nuint256 "]
-	contract_17 [label="contract X\ntests/contract_testcases/solana/override.sol:14:2-17:2"]
-	base_18 [label="base A\ntests/contract_testcases/solana/override.sol:15:15-16"]
-	base_19 [label="base B\ntests/contract_testcases/solana/override.sol:15:18-19"]
-	var_20 [label="variable foo\nvisibility public\ntests/contract_testcases/solana/override.sol:16:9-39"]
-	foo_21 [label="function foo\ncontract: X\ntests/contract_testcases/solana/override.sol:16:36-39\nsignature foo()\nvisibility public\nmutability view\noverride A\noverride B"]
-	returns_22 [label="returns\nuint256 "]
-	return_23 [label="return\nimplicit"]
-	storage_load_24 [label="storage load uint256\nimplicit"]
-	storage_var_25 [label="storage variable\nX.foo\nuint256 storage\nimplicit"]
-	contract_26 [label="contract Y\ntests/contract_testcases/solana/override.sol:17:2-19:2"]
-	base_27 [label="base X\ntests/contract_testcases/solana/override.sol:18:15-16"]
-	contract_28 [label="contract A2\ntests/contract_testcases/solana/override.sol:20:1-23:2"]
-	foo_29 [label="function foo\ncontract: A2\ntests/contract_testcases/solana/override.sol:22:5-51\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
-	returns_30 [label="returns\nuint256 "]
-	return_31 [label="return\ntests/contract_testcases/solana/override.sol:22:54-62"]
-	number_literal [label="uint256 literal: 1\ntests/contract_testcases/solana/override.sol:22:61-62"]
-	contract_33 [label="contract B2\ntests/contract_testcases/solana/override.sol:23:2-26:2"]
-	foo_34 [label="function foo\ncontract: B2\ntests/contract_testcases/solana/override.sol:25:5-51\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
-	returns_35 [label="returns\nuint256 "]
-	return_36 [label="return\ntests/contract_testcases/solana/override.sol:25:54-62"]
-	number_literal_37 [label="uint256 literal: 2\ntests/contract_testcases/solana/override.sol:25:61-62"]
-	contract_38 [label="contract X2\ntests/contract_testcases/solana/override.sol:26:2-29:2"]
-	base_39 [label="base A2\ntests/contract_testcases/solana/override.sol:27:16-18"]
-	base_40 [label="base B2\ntests/contract_testcases/solana/override.sol:27:20-22"]
-	var_41 [label="variable foo\nvisibility public\ntests/contract_testcases/solana/override.sol:28:9-37"]
-	foo_42 [label="function foo\ncontract: X2\ntests/contract_testcases/solana/override.sol:28:34-37\nsignature foo()\nvisibility public\nmutability view\noverride A2"]
-	returns_43 [label="returns\nuint256 "]
-	return_44 [label="return\nimplicit"]
-	storage_load_45 [label="storage load uint256\nimplicit"]
-	storage_var_46 [label="storage variable\nX2.foo\nuint256 storage\nimplicit"]
-	contract_47 [label="contract Y2\ntests/contract_testcases/solana/override.sol:29:2-31:2"]
-	base_48 [label="base X2\ntests/contract_testcases/solana/override.sol:30:16-18"]
-	contract_49 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-14"]
-	contract_50 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
+	returns_25 [label="returns\nuint256 "]
+	contract_26 [label="contract B\ntests/contract_testcases/solana/override.sol:11:2-14:2"]
+	foo_27 [label="function foo\ncontract: B\ntests/contract_testcases/solana/override.sol:13:5-43\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
+	returns_28 [label="returns\nuint256 "]
+	contract_29 [label="contract X\ntests/contract_testcases/solana/override.sol:14:2-17:2"]
+	base_30 [label="base A\ntests/contract_testcases/solana/override.sol:15:15-16"]
+	base_31 [label="base B\ntests/contract_testcases/solana/override.sol:15:18-19"]
+	var_32 [label="variable foo\nvisibility public\ntests/contract_testcases/solana/override.sol:16:9-39"]
+	foo_33 [label="function foo\ncontract: X\ntests/contract_testcases/solana/override.sol:16:36-39\nsignature foo()\nvisibility public\nmutability view\noverride A\noverride B"]
+	returns_34 [label="returns\nuint256 "]
+	return_35 [label="return\nimplicit"]
+	storage_load_36 [label="storage load uint256\nimplicit"]
+	storage_var_37 [label="storage variable\nX.foo\nuint256 storage\nimplicit"]
+	contract_38 [label="contract Y\ntests/contract_testcases/solana/override.sol:17:2-19:2"]
+	base_39 [label="base X\ntests/contract_testcases/solana/override.sol:18:15-16"]
+	contract_40 [label="contract A2\ntests/contract_testcases/solana/override.sol:20:1-23:2"]
+	foo_41 [label="function foo\ncontract: A2\ntests/contract_testcases/solana/override.sol:22:5-51\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
+	returns_42 [label="returns\nuint256 "]
+	return_43 [label="return\ntests/contract_testcases/solana/override.sol:22:54-62"]
+	number_literal_44 [label="uint256 literal: 1\ntests/contract_testcases/solana/override.sol:22:61-62"]
+	contract_45 [label="contract B2\ntests/contract_testcases/solana/override.sol:23:2-26:2"]
+	foo_46 [label="function foo\ncontract: B2\ntests/contract_testcases/solana/override.sol:25:5-51\nsignature foo()\nvisibility external\nmutability nonpayable\nvirtual"]
+	returns_47 [label="returns\nuint256 "]
+	return_48 [label="return\ntests/contract_testcases/solana/override.sol:25:54-62"]
+	number_literal_49 [label="uint256 literal: 2\ntests/contract_testcases/solana/override.sol:25:61-62"]
+	contract_50 [label="contract X2\ntests/contract_testcases/solana/override.sol:26:2-29:2"]
+	base_51 [label="base A2\ntests/contract_testcases/solana/override.sol:27:16-18"]
+	base_52 [label="base B2\ntests/contract_testcases/solana/override.sol:27:20-22"]
+	var_53 [label="variable foo\nvisibility public\ntests/contract_testcases/solana/override.sol:28:9-37"]
+	foo_54 [label="function foo\ncontract: X2\ntests/contract_testcases/solana/override.sol:28:34-37\nsignature foo()\nvisibility public\nmutability view\noverride A2"]
+	returns_55 [label="returns\nuint256 "]
+	return_56 [label="return\nimplicit"]
+	storage_load_57 [label="storage load uint256\nimplicit"]
+	storage_var_58 [label="storage variable\nX2.foo\nuint256 storage\nimplicit"]
+	contract_59 [label="contract Y2\ntests/contract_testcases/solana/override.sol:29:2-31:2"]
+	base_60 [label="base X2\ntests/contract_testcases/solana/override.sol:30:16-18"]
+	contract_61 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-14"]
+	contract_62 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
 	diagnostic [label="global variable has no bases contracts to override\nlevel Error\ntests/contract_testcases/solana/override.sol:3:14-22"]
 	diagnostic [label="global variable has no bases contracts to override\nlevel Error\ntests/contract_testcases/solana/override.sol:3:14-22"]
-	diagnostic_53 [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/override.sol:4:1-7:2"]
-	diagnostic_54 [label="'meh' does not override anything\nlevel Error\ntests/contract_testcases/solana/override.sol:6:29-32"]
-	diagnostic_55 [label="found interface 'A'\nlevel Debug\ntests/contract_testcases/solana/override.sol:8:1-11:2"]
-	diagnostic_56 [label="found interface 'B'\nlevel Debug\ntests/contract_testcases/solana/override.sol:11:2-14:2"]
-	diagnostic_57 [label="found contract 'X'\nlevel Debug\ntests/contract_testcases/solana/override.sol:14:2-17:2"]
-	diagnostic_58 [label="found contract 'Y'\nlevel Debug\ntests/contract_testcases/solana/override.sol:17:2-19:2"]
-	diagnostic_59 [label="found abstract contract 'A2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:20:1-23:2"]
-	diagnostic_60 [label="found abstract contract 'B2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:23:2-26:2"]
-	diagnostic_61 [label="found contract 'X2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:26:2-29:2"]
-	diagnostic_62 [label="function 'foo' missing overrides 'B2', specify 'override(B2,A2)'\nlevel Error\ntests/contract_testcases/solana/override.sol:28:21-33"]
-	diagnostic_63 [label="found contract 'Y2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:29:2-31:2"]
-	diagnostic_64 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:1-14"]
-	diagnostic_65 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
+	diagnostic_65 [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/override.sol:4:1-7:2"]
+	diagnostic_66 [label="'meh' does not override anything\nlevel Error\ntests/contract_testcases/solana/override.sol:6:29-32"]
+	diagnostic_67 [label="found interface 'A'\nlevel Debug\ntests/contract_testcases/solana/override.sol:8:1-11:2"]
+	diagnostic_68 [label="found interface 'B'\nlevel Debug\ntests/contract_testcases/solana/override.sol:11:2-14:2"]
+	diagnostic_69 [label="found contract 'X'\nlevel Debug\ntests/contract_testcases/solana/override.sol:14:2-17:2"]
+	diagnostic_70 [label="found contract 'Y'\nlevel Debug\ntests/contract_testcases/solana/override.sol:17:2-19:2"]
+	diagnostic_71 [label="found abstract contract 'A2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:20:1-23:2"]
+	diagnostic_72 [label="found abstract contract 'B2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:23:2-26:2"]
+	diagnostic_73 [label="found contract 'X2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:26:2-29:2"]
+	diagnostic_74 [label="function 'foo' missing overrides 'B2', specify 'override(B2,A2)'\nlevel Error\ntests/contract_testcases/solana/override.sol:28:21-33"]
+	diagnostic_75 [label="found contract 'Y2'\nlevel Debug\ntests/contract_testcases/solana/override.sol:29:2-31:2"]
+	diagnostic_76 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:1-14"]
+	diagnostic_77 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
 	structs -> S
 	structs -> S
+	free_functions -> inc [label="function"]
+	inc -> parameters [label="parameters"]
+	inc -> expr [label="body"]
+	expr -> assign [label="expr"]
+	assign -> structmember [label="left"]
+	structmember -> variable [label="var"]
+	assign -> add [label="right"]
+	add -> load [label="left"]
+	load -> structmember_11 [label="expr"]
+	structmember_11 -> variable_12 [label="var"]
+	add -> number_literal [label="right"]
 	contracts -> contract
 	contracts -> contract
 	contract -> base [label="base"]
 	contract -> base [label="base"]
 	contract -> var [label="variable"]
 	contract -> var [label="variable"]
@@ -71,58 +93,58 @@ strict digraph "tests/contract_testcases/solana/override.sol" {
 	meh -> return [label="body"]
 	meh -> return [label="body"]
 	return -> storage_load [label="expr"]
 	return -> storage_load [label="expr"]
 	storage_load -> storage_var [label="expr"]
 	storage_load -> storage_var [label="expr"]
-	contracts -> contract_11
-	contract_11 -> foo [label="function"]
-	foo -> returns_13 [label="returns"]
-	contracts -> contract_14
-	contract_14 -> foo_15 [label="function"]
-	foo_15 -> returns_16 [label="returns"]
-	contracts -> contract_17
-	contract_17 -> base_18 [label="base"]
-	contract_17 -> base_19 [label="base"]
-	contract_17 -> var_20 [label="variable"]
-	contract_17 -> foo_21 [label="function"]
-	foo_21 -> returns_22 [label="returns"]
-	foo_21 -> return_23 [label="body"]
-	return_23 -> storage_load_24 [label="expr"]
-	storage_load_24 -> storage_var_25 [label="expr"]
+	contracts -> contract_23
+	contract_23 -> foo [label="function"]
+	foo -> returns_25 [label="returns"]
 	contracts -> contract_26
 	contracts -> contract_26
-	contract_26 -> base_27 [label="base"]
-	contracts -> contract_28
-	contract_28 -> foo_29 [label="function"]
-	foo_29 -> returns_30 [label="returns"]
-	foo_29 -> return_31 [label="body"]
-	return_31 -> number_literal [label="expr"]
-	contracts -> contract_33
-	contract_33 -> foo_34 [label="function"]
-	foo_34 -> returns_35 [label="returns"]
-	foo_34 -> return_36 [label="body"]
-	return_36 -> number_literal_37 [label="expr"]
+	contract_26 -> foo_27 [label="function"]
+	foo_27 -> returns_28 [label="returns"]
+	contracts -> contract_29
+	contract_29 -> base_30 [label="base"]
+	contract_29 -> base_31 [label="base"]
+	contract_29 -> var_32 [label="variable"]
+	contract_29 -> foo_33 [label="function"]
+	foo_33 -> returns_34 [label="returns"]
+	foo_33 -> return_35 [label="body"]
+	return_35 -> storage_load_36 [label="expr"]
+	storage_load_36 -> storage_var_37 [label="expr"]
 	contracts -> contract_38
 	contracts -> contract_38
 	contract_38 -> base_39 [label="base"]
 	contract_38 -> base_39 [label="base"]
-	contract_38 -> base_40 [label="base"]
-	contract_38 -> var_41 [label="variable"]
-	contract_38 -> foo_42 [label="function"]
-	foo_42 -> returns_43 [label="returns"]
-	foo_42 -> return_44 [label="body"]
-	return_44 -> storage_load_45 [label="expr"]
-	storage_load_45 -> storage_var_46 [label="expr"]
-	contracts -> contract_47
-	contract_47 -> base_48 [label="base"]
-	contracts -> contract_49
+	contracts -> contract_40
+	contract_40 -> foo_41 [label="function"]
+	foo_41 -> returns_42 [label="returns"]
+	foo_41 -> return_43 [label="body"]
+	return_43 -> number_literal_44 [label="expr"]
+	contracts -> contract_45
+	contract_45 -> foo_46 [label="function"]
+	foo_46 -> returns_47 [label="returns"]
+	foo_46 -> return_48 [label="body"]
+	return_48 -> number_literal_49 [label="expr"]
 	contracts -> contract_50
 	contracts -> contract_50
+	contract_50 -> base_51 [label="base"]
+	contract_50 -> base_52 [label="base"]
+	contract_50 -> var_53 [label="variable"]
+	contract_50 -> foo_54 [label="function"]
+	foo_54 -> returns_55 [label="returns"]
+	foo_54 -> return_56 [label="body"]
+	return_56 -> storage_load_57 [label="expr"]
+	storage_load_57 -> storage_var_58 [label="expr"]
+	contracts -> contract_59
+	contract_59 -> base_60 [label="base"]
+	contracts -> contract_61
+	contracts -> contract_62
 	diagnostics -> diagnostic [label="Error"]
 	diagnostics -> diagnostic [label="Error"]
-	diagnostics -> diagnostic_53 [label="Debug"]
-	diagnostics -> diagnostic_54 [label="Error"]
-	diagnostics -> diagnostic_55 [label="Debug"]
-	diagnostics -> diagnostic_56 [label="Debug"]
-	diagnostics -> diagnostic_57 [label="Debug"]
-	diagnostics -> diagnostic_58 [label="Debug"]
-	diagnostics -> diagnostic_59 [label="Debug"]
-	diagnostics -> diagnostic_60 [label="Debug"]
-	diagnostics -> diagnostic_61 [label="Debug"]
-	diagnostics -> diagnostic_62 [label="Error"]
-	diagnostics -> diagnostic_63 [label="Debug"]
-	diagnostics -> diagnostic_64 [label="Debug"]
 	diagnostics -> diagnostic_65 [label="Debug"]
 	diagnostics -> diagnostic_65 [label="Debug"]
+	diagnostics -> diagnostic_66 [label="Error"]
+	diagnostics -> diagnostic_67 [label="Debug"]
+	diagnostics -> diagnostic_68 [label="Debug"]
+	diagnostics -> diagnostic_69 [label="Debug"]
+	diagnostics -> diagnostic_70 [label="Debug"]
+	diagnostics -> diagnostic_71 [label="Debug"]
+	diagnostics -> diagnostic_72 [label="Debug"]
+	diagnostics -> diagnostic_73 [label="Debug"]
+	diagnostics -> diagnostic_74 [label="Error"]
+	diagnostics -> diagnostic_75 [label="Debug"]
+	diagnostics -> diagnostic_76 [label="Debug"]
+	diagnostics -> diagnostic_77 [label="Debug"]
 }
 }

+ 3 - 3
tests/contract_testcases/solana/structs/parse_structs_06.dot

@@ -2,11 +2,11 @@ strict digraph "tests/contract_testcases/solana/structs/parse_structs_06.sol" {
 	Foo [label="name:Foo\ncontract: test_struct_parsing\ntests/contract_testcases/solana/structs/parse_structs_06.sol:3:20-23\nfield name:x ty:bool\nfield name:y ty:struct test_struct_parsing.Foo"]
 	Foo [label="name:Foo\ncontract: test_struct_parsing\ntests/contract_testcases/solana/structs/parse_structs_06.sol:3:20-23\nfield name:x ty:bool\nfield name:y ty:struct test_struct_parsing.Foo"]
 	contract [label="contract test_struct_parsing\ntests/contract_testcases/solana/structs/parse_structs_06.sol:2:9-7:10"]
 	contract [label="contract test_struct_parsing\ntests/contract_testcases/solana/structs/parse_structs_06.sol:2:9-7:10"]
 	diagnostic [label="found contract 'test_struct_parsing'\nlevel Debug\ntests/contract_testcases/solana/structs/parse_structs_06.sol:2:9-7:10"]
 	diagnostic [label="found contract 'test_struct_parsing'\nlevel Debug\ntests/contract_testcases/solana/structs/parse_structs_06.sol:2:9-7:10"]
-	diagnostic_7 [label="struct 'Foo' has infinite size\nlevel Error\ntests/contract_testcases/solana/structs/parse_structs_06.sol:3:20-23"]
+	diagnostic_6 [label="struct 'Foo' has infinite size\nlevel Error\ntests/contract_testcases/solana/structs/parse_structs_06.sol:3:20-23"]
 	note [label="recursive field 'y'\ntests/contract_testcases/solana/structs/parse_structs_06.sol:5:17-22"]
 	note [label="recursive field 'y'\ntests/contract_testcases/solana/structs/parse_structs_06.sol:5:17-22"]
 	structs -> Foo
 	structs -> Foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
-	diagnostic_7 -> note [label="note"]
+	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostic_6 -> note [label="note"]
 }
 }

+ 29 - 15
tests/contract_testcases/solana/type_called_error.dot

@@ -1,38 +1,52 @@
 strict digraph "tests/contract_testcases/solana/type_called_error.sol" {
 strict digraph "tests/contract_testcases/solana/type_called_error.sol" {
 	error [label="name:error\ntests/contract_testcases/solana/type_called_error.sol:1:8-13\nfield name:f1 ty:int256"]
 	error [label="name:error\ntests/contract_testcases/solana/type_called_error.sol:1:8-13\nfield name:f1 ty:int256"]
+	member [label="function member\ntests/contract_testcases/solana/type_called_error.sol:2:1-3:44\nsignature member((int256))\nvisibility internal\nmutability pure"]
+	parameters [label="parameters\nstruct error e"]
+	returns [label="returns\nint256 "]
+	return [label="return\ntests/contract_testcases/solana/type_called_error.sol:4:2-13"]
+	load [label="load int256\ntests/contract_testcases/solana/type_called_error.sol:4:2-13"]
+	structmember [label="struct member #0 int256\ntests/contract_testcases/solana/type_called_error.sol:4:11-13"]
+	variable [label="variable: e\nstruct error\ntests/contract_testcases/solana/type_called_error.sol:4:9-10"]
 	contract [label="contract c\ntests/contract_testcases/solana/type_called_error.sol:8:1-16:2"]
 	contract [label="contract c\ntests/contract_testcases/solana/type_called_error.sol:8:1-16:2"]
 	var [label="variable v1\nvisibility public\ntests/contract_testcases/solana/type_called_error.sol:10:2-17"]
 	var [label="variable v1\nvisibility public\ntests/contract_testcases/solana/type_called_error.sol:10:2-17"]
 	v1 [label="function v1\ncontract: c\ntests/contract_testcases/solana/type_called_error.sol:10:15-17\nsignature v1()\nvisibility public\nmutability view"]
 	v1 [label="function v1\ncontract: c\ntests/contract_testcases/solana/type_called_error.sol:10:15-17\nsignature v1()\nvisibility public\nmutability view"]
-	returns [label="returns\nstruct error "]
-	return [label="return\nimplicit"]
+	returns_14 [label="returns\nstruct error "]
+	return_15 [label="return\nimplicit"]
 	storage_load [label="storage load struct error\nimplicit"]
 	storage_load [label="storage load struct error\nimplicit"]
 	storage_var [label="storage variable\nc.v1\nstruct error storage\nimplicit"]
 	storage_var [label="storage variable\nc.v1\nstruct error storage\nimplicit"]
 	test [label="function test\ncontract: c\ntests/contract_testcases/solana/type_called_error.sol:12:2-54\nsignature test((int256))\nvisibility internal\nmutability pure"]
 	test [label="function test\ncontract: c\ntests/contract_testcases/solana/type_called_error.sol:12:2-54\nsignature test((int256))\nvisibility internal\nmutability pure"]
-	parameters [label="parameters\nstruct error e"]
-	returns_12 [label="returns\nstruct error "]
+	parameters_19 [label="parameters\nstruct error e"]
+	returns_20 [label="returns\nstruct error "]
 	expr [label="expression\ntests/contract_testcases/solana/type_called_error.sol:13:3-13"]
 	expr [label="expression\ntests/contract_testcases/solana/type_called_error.sol:13:3-13"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/type_called_error.sol:13:3-13"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/type_called_error.sol:13:3-13"]
 	internal_function [label="function(struct error) internal pure returns (void)\nfree function member\ntests/contract_testcases/solana/type_called_error.sol:13:3-13"]
 	internal_function [label="function(struct error) internal pure returns (void)\nfree function member\ntests/contract_testcases/solana/type_called_error.sol:13:3-13"]
-	variable [label="variable: e\nstruct error\ntests/contract_testcases/solana/type_called_error.sol:13:3-4"]
-	return_17 [label="return\ntests/contract_testcases/solana/type_called_error.sol:14:3-11"]
-	variable_18 [label="variable: e\nstruct error\ntests/contract_testcases/solana/type_called_error.sol:14:10-11"]
+	variable_24 [label="variable: e\nstruct error\ntests/contract_testcases/solana/type_called_error.sol:13:3-4"]
+	return_25 [label="return\ntests/contract_testcases/solana/type_called_error.sol:14:3-11"]
+	variable_26 [label="variable: e\nstruct error\ntests/contract_testcases/solana/type_called_error.sol:14:10-11"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/type_called_error.sol:8:1-16:2"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/type_called_error.sol:8:1-16:2"]
 	structs -> error
 	structs -> error
+	free_functions -> member [label="function"]
+	member -> parameters [label="parameters"]
+	member -> returns [label="returns"]
+	member -> return [label="body"]
+	return -> load [label="expr"]
+	load -> structmember [label="expr"]
+	structmember -> variable [label="var"]
 	contracts -> contract
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> var [label="variable"]
 	contract -> v1 [label="function"]
 	contract -> v1 [label="function"]
-	v1 -> returns [label="returns"]
-	v1 -> return [label="body"]
-	return -> storage_load [label="expr"]
+	v1 -> returns_14 [label="returns"]
+	v1 -> return_15 [label="body"]
+	return_15 -> storage_load [label="expr"]
 	storage_load -> storage_var [label="expr"]
 	storage_load -> storage_var [label="expr"]
 	contract -> test [label="function"]
 	contract -> test [label="function"]
-	test -> parameters [label="parameters"]
-	test -> returns_12 [label="returns"]
+	test -> parameters_19 [label="parameters"]
+	test -> returns_20 [label="returns"]
 	test -> expr [label="body"]
 	test -> expr [label="body"]
 	expr -> call_internal_function [label="expr"]
 	expr -> call_internal_function [label="expr"]
 	call_internal_function -> internal_function [label="function"]
 	call_internal_function -> internal_function [label="function"]
-	call_internal_function -> variable [label="arg #0"]
-	expr -> return_17 [label="next"]
-	return_17 -> variable_18 [label="expr"]
+	call_internal_function -> variable_24 [label="arg #0"]
+	expr -> return_25 [label="next"]
+	return_25 -> variable_26 [label="expr"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
 }
 }

+ 12 - 8
tests/contract_testcases/solana/type_decl_broken_more.dot

@@ -1,22 +1,26 @@
 strict digraph "tests/contract_testcases/solana/type_decl_broken_more.sol" {
 strict digraph "tests/contract_testcases/solana/type_decl_broken_more.sol" {
 	Addr [label="name:Addr ty:address payable\ntests/contract_testcases/solana/type_decl.sol:1:1-2:29"]
 	Addr [label="name:Addr ty:address payable\ntests/contract_testcases/solana/type_decl.sol:1:1-2:29"]
 	Binary [label="name:Binary ty:bool\ncontract: x\ntests/contract_testcases/solana/type_decl.sol:5:2-21"]
 	Binary [label="name:Binary ty:bool\ncontract: x\ntests/contract_testcases/solana/type_decl.sol:5:2-21"]
+	bar [label="function bar\ntests/contract_testcases/solana/type_decl_broken_more.sol:4:1-5:24\nsignature bar(int256)\nvisibility internal\nmutability nonpayable"]
+	parameters [label="parameters\nint256 Addr"]
 	contract [label="contract x\ntests/contract_testcases/solana/type_decl.sol:3:1-8:2"]
 	contract [label="contract x\ntests/contract_testcases/solana/type_decl.sol:3:1-8:2"]
 	f [label="function f\ncontract: x\ntests/contract_testcases/solana/type_decl.sol:7:2-33\nsignature f(bytes32,bool)\nvisibility public\nmutability nonpayable"]
 	f [label="function f\ncontract: x\ntests/contract_testcases/solana/type_decl.sol:7:2-33\nsignature f(bytes32,bool)\nvisibility public\nmutability nonpayable"]
-	parameters [label="parameters\nusertype Addr \nusertype x.Binary "]
+	parameters_10 [label="parameters\nusertype Addr \nusertype x.Binary "]
 	diagnostic [label="'Addr' is an user type\nlevel Error\ntests/contract_testcases/solana/type_decl_broken_more.sol:3:14-18"]
 	diagnostic [label="'Addr' is an user type\nlevel Error\ntests/contract_testcases/solana/type_decl_broken_more.sol:3:14-18"]
-	diagnostic_10 [label="declaration of 'Addr' shadows type\nlevel Warning\ntests/contract_testcases/solana/type_decl_broken_more.sol:5:18-22"]
+	diagnostic_13 [label="declaration of 'Addr' shadows type\nlevel Warning\ntests/contract_testcases/solana/type_decl_broken_more.sol:5:18-22"]
 	note [label="previous declaration of type\ntests/contract_testcases/solana/type_decl.sol:2:6-10"]
 	note [label="previous declaration of type\ntests/contract_testcases/solana/type_decl.sol:2:6-10"]
-	diagnostic_12 [label="found contract 'x'\nlevel Debug\ntests/contract_testcases/solana/type_decl.sol:3:1-8:2"]
-	diagnostic_13 [label="function can be declared 'pure'\nlevel Warning\ntests/contract_testcases/solana/type_decl.sol:7:2-33"]
+	diagnostic_15 [label="found contract 'x'\nlevel Debug\ntests/contract_testcases/solana/type_decl.sol:3:1-8:2"]
+	diagnostic_16 [label="function can be declared 'pure'\nlevel Warning\ntests/contract_testcases/solana/type_decl.sol:7:2-33"]
 	types -> Addr
 	types -> Addr
 	types -> Binary
 	types -> Binary
+	free_functions -> bar [label="function"]
+	bar -> parameters [label="parameters"]
 	contracts -> contract
 	contracts -> contract
 	contract -> f [label="function"]
 	contract -> f [label="function"]
-	f -> parameters [label="parameters"]
+	f -> parameters_10 [label="parameters"]
 	diagnostics -> diagnostic [label="Error"]
 	diagnostics -> diagnostic [label="Error"]
-	diagnostics -> diagnostic_10 [label="Warning"]
-	diagnostic_10 -> note [label="note"]
-	diagnostics -> diagnostic_12 [label="Debug"]
 	diagnostics -> diagnostic_13 [label="Warning"]
 	diagnostics -> diagnostic_13 [label="Warning"]
+	diagnostic_13 -> note [label="note"]
+	diagnostics -> diagnostic_15 [label="Debug"]
+	diagnostics -> diagnostic_16 [label="Warning"]
 }
 }

+ 69 - 25
tests/contract_testcases/solana/using_import.dot

@@ -1,38 +1,82 @@
 strict digraph "tests/contract_testcases/solana/using_import.sol" {
 strict digraph "tests/contract_testcases/solana/using_import.sol" {
 	S [label="name:S\ntests/contract_testcases/solana/simple.sol:3:8-9\nfield name:f1 ty:int64\nfield name:f2 ty:bool"]
 	S [label="name:S\ntests/contract_testcases/solana/simple.sol:3:8-9\nfield name:f1 ty:int64\nfield name:f2 ty:bool"]
+	inc [label="function inc\ntests/contract_testcases/solana/simple.sol:6:2-7:23\nsignature inc((int64,bool))\nvisibility internal\nmutability pure"]
+	parameters [label="parameters\nstruct S s"]
+	expr [label="expression\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	assign [label="assign\nvoid\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	structmember [label="struct member #0 int64\ntests/contract_testcases/solana/simple.sol:7:28-30"]
+	variable [label="variable: s\nstruct S\ntests/contract_testcases/solana/simple.sol:7:26-27"]
+	add [label="add\nint64\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	load [label="load int64\ntests/contract_testcases/solana/simple.sol:7:26-35"]
+	structmember_11 [label="struct member #0 int64\ntests/contract_testcases/solana/simple.sol:7:28-30"]
+	variable_12 [label="variable: s\nstruct S\ntests/contract_testcases/solana/simple.sol:7:26-27"]
+	number_literal [label="int64 literal: 1\ntests/contract_testcases/solana/simple.sol:7:34-35"]
+	dec [label="function dec\ntests/contract_testcases/solana/using_import.sol:2:1-3:31\nsignature dec((int64,bool))\nvisibility internal\nmutability pure"]
+	parameters_15 [label="parameters\nstruct S s"]
+	expr_16 [label="expression\ntests/contract_testcases/solana/using_import.sol:3:34-43"]
+	assign_17 [label="assign\nvoid\ntests/contract_testcases/solana/using_import.sol:3:34-43"]
+	structmember_18 [label="struct member #0 int64\ntests/contract_testcases/solana/using_import.sol:3:36-38"]
+	variable_19 [label="variable: s\nstruct S\ntests/contract_testcases/solana/using_import.sol:3:34-35"]
+	subtract [label="subtract\nint64\ntests/contract_testcases/solana/using_import.sol:3:34-43"]
+	load_21 [label="load int64\ntests/contract_testcases/solana/using_import.sol:3:34-43"]
+	structmember_22 [label="struct member #0 int64\ntests/contract_testcases/solana/using_import.sol:3:36-38"]
+	variable_23 [label="variable: s\nstruct S\ntests/contract_testcases/solana/using_import.sol:3:34-35"]
+	number_literal_24 [label="int64 literal: 1\ntests/contract_testcases/solana/using_import.sol:3:42-43"]
 	contract [label="contract c\ntests/contract_testcases/solana/using_import.sol:5:1-11:2"]
 	contract [label="contract c\ntests/contract_testcases/solana/using_import.sol:5:1-11:2"]
 	test [label="function test\ncontract: c\ntests/contract_testcases/solana/using_import.sol:7:2-35\nsignature test((int64,bool))\nvisibility public\nmutability nonpayable"]
 	test [label="function test\ncontract: c\ntests/contract_testcases/solana/using_import.sol:7:2-35\nsignature test((int64,bool))\nvisibility public\nmutability nonpayable"]
-	parameters [label="parameters\nstruct S s"]
-	expr [label="expression\ntests/contract_testcases/solana/using_import.sol:8:3-10"]
+	parameters_28 [label="parameters\nstruct S s"]
+	expr_29 [label="expression\ntests/contract_testcases/solana/using_import.sol:8:3-10"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/using_import.sol:8:3-10"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/using_import.sol:8:3-10"]
 	internal_function [label="function(struct S) internal pure returns (void)\nfree function inc\ntests/contract_testcases/solana/using_import.sol:8:3-10"]
 	internal_function [label="function(struct S) internal pure returns (void)\nfree function inc\ntests/contract_testcases/solana/using_import.sol:8:3-10"]
-	variable [label="variable: s\nstruct S\ntests/contract_testcases/solana/using_import.sol:8:3-4"]
-	expr_10 [label="expression\ntests/contract_testcases/solana/using_import.sol:9:3-10"]
-	call_internal_function_11 [label="call internal function\ntests/contract_testcases/solana/using_import.sol:9:3-10"]
-	internal_function_12 [label="function(struct S) internal pure returns (void)\nfree function dec\ntests/contract_testcases/solana/using_import.sol:9:3-10"]
-	variable_13 [label="variable: s\nstruct S\ntests/contract_testcases/solana/using_import.sol:9:3-4"]
-	contract_14 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-14"]
-	contract_15 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
+	variable_32 [label="variable: s\nstruct S\ntests/contract_testcases/solana/using_import.sol:8:3-4"]
+	expr_33 [label="expression\ntests/contract_testcases/solana/using_import.sol:9:3-10"]
+	call_internal_function_34 [label="call internal function\ntests/contract_testcases/solana/using_import.sol:9:3-10"]
+	internal_function_35 [label="function(struct S) internal pure returns (void)\nfree function dec\ntests/contract_testcases/solana/using_import.sol:9:3-10"]
+	variable_36 [label="variable: s\nstruct S\ntests/contract_testcases/solana/using_import.sol:9:3-4"]
+	contract_37 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-14"]
+	contract_38 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/using_import.sol:5:1-11:2"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/using_import.sol:5:1-11:2"]
-	diagnostic_18 [label="function can be declared 'pure'\nlevel Warning\ntests/contract_testcases/solana/using_import.sol:7:2-35"]
-	diagnostic_19 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:1-14"]
-	diagnostic_20 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
+	diagnostic_41 [label="function can be declared 'pure'\nlevel Warning\ntests/contract_testcases/solana/using_import.sol:7:2-35"]
+	diagnostic_42 [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:1-14"]
+	diagnostic_43 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:13"]
 	structs -> S
 	structs -> S
+	free_functions -> inc [label="function"]
+	inc -> parameters [label="parameters"]
+	inc -> expr [label="body"]
+	expr -> assign [label="expr"]
+	assign -> structmember [label="left"]
+	structmember -> variable [label="var"]
+	assign -> add [label="right"]
+	add -> load [label="left"]
+	load -> structmember_11 [label="expr"]
+	structmember_11 -> variable_12 [label="var"]
+	add -> number_literal [label="right"]
+	free_functions -> dec [label="function"]
+	dec -> parameters_15 [label="parameters"]
+	dec -> expr_16 [label="body"]
+	expr_16 -> assign_17 [label="expr"]
+	assign_17 -> structmember_18 [label="left"]
+	structmember_18 -> variable_19 [label="var"]
+	assign_17 -> subtract [label="right"]
+	subtract -> load_21 [label="left"]
+	load_21 -> structmember_22 [label="expr"]
+	structmember_22 -> variable_23 [label="var"]
+	subtract -> number_literal_24 [label="right"]
 	contracts -> contract
 	contracts -> contract
 	contract -> test [label="function"]
 	contract -> test [label="function"]
-	test -> parameters [label="parameters"]
-	test -> expr [label="body"]
-	expr -> call_internal_function [label="expr"]
+	test -> parameters_28 [label="parameters"]
+	test -> expr_29 [label="body"]
+	expr_29 -> call_internal_function [label="expr"]
 	call_internal_function -> internal_function [label="function"]
 	call_internal_function -> internal_function [label="function"]
-	call_internal_function -> variable [label="arg #0"]
-	expr -> expr_10 [label="next"]
-	expr_10 -> call_internal_function_11 [label="expr"]
-	call_internal_function_11 -> internal_function_12 [label="function"]
-	call_internal_function_11 -> variable_13 [label="arg #0"]
-	contracts -> contract_14
-	contracts -> contract_15
+	call_internal_function -> variable_32 [label="arg #0"]
+	expr_29 -> expr_33 [label="next"]
+	expr_33 -> call_internal_function_34 [label="expr"]
+	call_internal_function_34 -> internal_function_35 [label="function"]
+	call_internal_function_34 -> variable_36 [label="arg #0"]
+	contracts -> contract_37
+	contracts -> contract_38
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_18 [label="Warning"]
-	diagnostics -> diagnostic_19 [label="Debug"]
-	diagnostics -> diagnostic_20 [label="Debug"]
+	diagnostics -> diagnostic_41 [label="Warning"]
+	diagnostics -> diagnostic_42 [label="Debug"]
+	diagnostics -> diagnostic_43 [label="Debug"]
 }
 }

+ 41 - 21
tests/contract_testcases/solana/using_list.dot

@@ -1,36 +1,56 @@
 strict digraph "tests/contract_testcases/solana/using_list.sol" {
 strict digraph "tests/contract_testcases/solana/using_list.sol" {
+	id [label="function id\ntests/contract_testcases/solana/using_list.sol:1:1-40\nsignature id(uint256)\nvisibility internal\nmutability pure"]
+	parameters [label="parameters\nuint256 x"]
+	returns [label="returns\nuint256 "]
+	return [label="return\ntests/contract_testcases/solana/using_list.sol:2:5-13"]
+	variable [label="variable: x\nuint256\ntests/contract_testcases/solana/using_list.sol:2:12-13"]
+	zero [label="function zero\ntests/contract_testcases/solana/using_list.sol:4:1-5:40\nsignature zero(uint256)\nvisibility internal\nmutability pure"]
+	parameters_8 [label="parameters\nuint256 "]
+	returns_9 [label="returns\nuint256 "]
+	return_10 [label="return\ntests/contract_testcases/solana/using_list.sol:6:5-13"]
+	number_literal [label="uint256 literal: 0\ntests/contract_testcases/solana/using_list.sol:6:12-13"]
 	contract [label="contract C\ntests/contract_testcases/solana/using_list.sol:8:1-19:2"]
 	contract [label="contract C\ntests/contract_testcases/solana/using_list.sol:8:1-19:2"]
 	using [label="using for uint256\nfunction id tests/contract_testcases/solana/using_list.sol:1:1-40\nfunction zero tests/contract_testcases/solana/using_list.sol:4:1-5:40"]
 	using [label="using for uint256\nfunction id tests/contract_testcases/solana/using_list.sol:1:1-40\nfunction zero tests/contract_testcases/solana/using_list.sol:4:1-5:40"]
 	f [label="function f\ncontract: C\ntests/contract_testcases/solana/using_list.sol:10:5-51\nsignature f(uint256)\nvisibility external\nmutability pure"]
 	f [label="function f\ncontract: C\ntests/contract_testcases/solana/using_list.sol:10:5-51\nsignature f(uint256)\nvisibility external\nmutability pure"]
-	parameters [label="parameters\nuint256 z"]
-	returns [label="returns\nuint256 "]
-	return [label="return\ntests/contract_testcases/solana/using_list.sol:11:9-22"]
+	parameters_16 [label="parameters\nuint256 z"]
+	returns_17 [label="returns\nuint256 "]
+	return_18 [label="return\ntests/contract_testcases/solana/using_list.sol:11:9-22"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/using_list.sol:11:16-22"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/using_list.sol:11:16-22"]
 	internal_function [label="function(uint256) internal pure returns (uint256)\nfree function id\ntests/contract_testcases/solana/using_list.sol:11:16-22"]
 	internal_function [label="function(uint256) internal pure returns (uint256)\nfree function id\ntests/contract_testcases/solana/using_list.sol:11:16-22"]
-	variable [label="variable: z\nuint256\ntests/contract_testcases/solana/using_list.sol:11:16-17"]
+	variable_21 [label="variable: z\nuint256\ntests/contract_testcases/solana/using_list.sol:11:16-17"]
 	g [label="function g\ncontract: C\ntests/contract_testcases/solana/using_list.sol:14:5-52\nsignature g(uint256)\nvisibility external\nmutability pure"]
 	g [label="function g\ncontract: C\ntests/contract_testcases/solana/using_list.sol:14:5-52\nsignature g(uint256)\nvisibility external\nmutability pure"]
-	parameters_12 [label="parameters\nuint256 z"]
-	returns_13 [label="returns\nuint256 "]
-	return_14 [label="return\ntests/contract_testcases/solana/using_list.sol:15:9-24"]
-	call_internal_function_15 [label="call internal function\ntests/contract_testcases/solana/using_list.sol:15:16-24"]
-	internal_function_16 [label="function(uint256) internal pure returns (uint256)\nfree function zero\ntests/contract_testcases/solana/using_list.sol:15:16-24"]
-	variable_17 [label="variable: z\nuint256\ntests/contract_testcases/solana/using_list.sol:15:16-17"]
+	parameters_23 [label="parameters\nuint256 z"]
+	returns_24 [label="returns\nuint256 "]
+	return_25 [label="return\ntests/contract_testcases/solana/using_list.sol:15:9-24"]
+	call_internal_function_26 [label="call internal function\ntests/contract_testcases/solana/using_list.sol:15:16-24"]
+	internal_function_27 [label="function(uint256) internal pure returns (uint256)\nfree function zero\ntests/contract_testcases/solana/using_list.sol:15:16-24"]
+	variable_28 [label="variable: z\nuint256\ntests/contract_testcases/solana/using_list.sol:15:16-17"]
 	diagnostic [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/using_list.sol:8:1-19:2"]
 	diagnostic [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/using_list.sol:8:1-19:2"]
+	free_functions -> id [label="function"]
+	id -> parameters [label="parameters"]
+	id -> returns [label="returns"]
+	id -> return [label="body"]
+	return -> variable [label="expr"]
+	free_functions -> zero [label="function"]
+	zero -> parameters_8 [label="parameters"]
+	zero -> returns_9 [label="returns"]
+	zero -> return_10 [label="body"]
+	return_10 -> number_literal [label="expr"]
 	contracts -> contract
 	contracts -> contract
 	contract -> using [label="base"]
 	contract -> using [label="base"]
 	contract -> f [label="function"]
 	contract -> f [label="function"]
-	f -> parameters [label="parameters"]
-	f -> returns [label="returns"]
-	f -> return [label="body"]
-	return -> call_internal_function [label="expr"]
+	f -> parameters_16 [label="parameters"]
+	f -> returns_17 [label="returns"]
+	f -> return_18 [label="body"]
+	return_18 -> call_internal_function [label="expr"]
 	call_internal_function -> internal_function [label="function"]
 	call_internal_function -> internal_function [label="function"]
-	call_internal_function -> variable [label="arg #0"]
+	call_internal_function -> variable_21 [label="arg #0"]
 	contract -> g [label="function"]
 	contract -> g [label="function"]
-	g -> parameters_12 [label="parameters"]
-	g -> returns_13 [label="returns"]
-	g -> return_14 [label="body"]
-	return_14 -> call_internal_function_15 [label="expr"]
-	call_internal_function_15 -> internal_function_16 [label="function"]
-	call_internal_function_15 -> variable_17 [label="arg #0"]
+	g -> parameters_23 [label="parameters"]
+	g -> returns_24 [label="returns"]
+	g -> return_25 [label="body"]
+	return_25 -> call_internal_function_26 [label="expr"]
+	call_internal_function_26 -> internal_function_27 [label="function"]
+	call_internal_function_26 -> variable_28 [label="arg #0"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
 }
 }

+ 21 - 7
tests/contract_testcases/solana/using_literal.dot

@@ -1,18 +1,32 @@
 strict digraph "tests/contract_testcases/solana/using_literal.sol" {
 strict digraph "tests/contract_testcases/solana/using_literal.sol" {
+	double [label="function double\ntests/contract_testcases/solana/using_literal.sol:1:1-42\nsignature double(int256)\nvisibility internal\nmutability pure"]
+	parameters [label="parameters\nint256 x"]
+	returns [label="returns\nint256 "]
+	return [label="return\ntests/contract_testcases/solana/using_literal.sol:1:45-57"]
+	multiply [label="multiply\nint256\ntests/contract_testcases/solana/using_literal.sol:1:52-57"]
+	variable [label="variable: x\nint256\ntests/contract_testcases/solana/using_literal.sol:1:52-53"]
+	number_literal [label="int256 literal: 2\ntests/contract_testcases/solana/using_literal.sol:1:56-57"]
 	contract [label="contract C\ntests/contract_testcases/solana/using_literal.sol:4:1-9:2"]
 	contract [label="contract C\ntests/contract_testcases/solana/using_literal.sol:4:1-9:2"]
 	foo [label="function foo\ncontract: C\ntests/contract_testcases/solana/using_literal.sol:6:2-42\nsignature foo()\nvisibility public\nmutability pure"]
 	foo [label="function foo\ncontract: C\ntests/contract_testcases/solana/using_literal.sol:6:2-42\nsignature foo()\nvisibility public\nmutability pure"]
-	returns [label="returns\nint256 "]
-	return [label="return\ntests/contract_testcases/solana/using_literal.sol:7:3-21"]
+	returns_12 [label="returns\nint256 "]
+	return_13 [label="return\ntests/contract_testcases/solana/using_literal.sol:7:3-21"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/using_literal.sol:7:10-21"]
 	call_internal_function [label="call internal function\ntests/contract_testcases/solana/using_literal.sol:7:10-21"]
 	internal_function [label="function(int256) internal pure returns (int256)\nfree function double\ntests/contract_testcases/solana/using_literal.sol:7:10-21"]
 	internal_function [label="function(int256) internal pure returns (int256)\nfree function double\ntests/contract_testcases/solana/using_literal.sol:7:10-21"]
-	number_literal [label="int256 literal: 42\ntests/contract_testcases/solana/using_literal.sol:7:10-12"]
+	number_literal_16 [label="int256 literal: 42\ntests/contract_testcases/solana/using_literal.sol:7:10-12"]
 	diagnostic [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/using_literal.sol:4:1-9:2"]
 	diagnostic [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/using_literal.sol:4:1-9:2"]
+	free_functions -> double [label="function"]
+	double -> parameters [label="parameters"]
+	double -> returns [label="returns"]
+	double -> return [label="body"]
+	return -> multiply [label="expr"]
+	multiply -> variable [label="left"]
+	multiply -> number_literal [label="right"]
 	contracts -> contract
 	contracts -> contract
 	contract -> foo [label="function"]
 	contract -> foo [label="function"]
-	foo -> returns [label="returns"]
-	foo -> return [label="body"]
-	return -> call_internal_function [label="expr"]
+	foo -> returns_12 [label="returns"]
+	foo -> return_13 [label="body"]
+	return_13 -> call_internal_function [label="expr"]
 	call_internal_function -> internal_function [label="function"]
 	call_internal_function -> internal_function [label="function"]
-	call_internal_function -> number_literal [label="arg #0"]
+	call_internal_function -> number_literal_16 [label="arg #0"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
 }
 }

+ 6 - 6
tests/contract_testcases/substrate/account_info.dot

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

+ 2 - 2
tests/contract_testcases/substrate/arrays/array_dimensions.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions.sol" {
 strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions.sol:2:9-4:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions.sol:2:9-4:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions.sol:2:9-4:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions.sol:2:9-4:10"]
-	diagnostic_5 [label="zero size array not permitted\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions.sol:3:18-25"]
+	diagnostic_4 [label="zero size array not permitted\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions.sol:3:18-25"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/array_dimensions_01.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions_01.sol" {
 strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions_01.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_01.sol:2:9-4:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_01.sol:2:9-4:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_01.sol:2:9-4:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_01.sol:2:9-4:10"]
-	diagnostic_5 [label="negative literal -10 not allowed for unsigned type 'uint256'\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_01.sol:3:18-21"]
+	diagnostic_4 [label="negative literal -10 not allowed for unsigned type 'uint256'\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_01.sol:3:18-21"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/array_dimensions_02.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions_02.sol" {
 strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions_02.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_02.sol:2:9-4:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_02.sol:2:9-4:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_02.sol:2:9-4:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_02.sol:2:9-4:10"]
-	diagnostic_5 [label="zero size array not permitted\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_02.sol:3:18-24"]
+	diagnostic_4 [label="zero size array not permitted\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_02.sol:3:18-24"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/array_dimensions_03.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions_03.so
 	e [label="name: e\ncontract: foo\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:3:13-34\nvalue: e1\nvalue: e2\nvalue: e3"]
 	e [label="name: e\ncontract: foo\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:3:13-34\nvalue: e1\nvalue: e2\nvalue: e3"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:2:9-5:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:2:9-5:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:2:9-5:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:2:9-5:10"]
-	diagnostic_7 [label="divide by zero\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:4:15-20"]
+	diagnostic_6 [label="divide by zero\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_03.sol:4:15-20"]
 	enums -> e
 	enums -> e
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/array_dimensions_04.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/array_dimensions_04.so
 	bar [label="name:bar\ncontract: foo\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:3:20-23\nfield name:x ty:int32"]
 	bar [label="name:bar\ncontract: foo\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:3:20-23\nfield name:x ty:int32"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:2:9-7:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:2:9-7:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:2:9-7:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:2:9-7:10"]
-	diagnostic_7 [label="divide by zero\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:6:17-22"]
+	diagnostic_6 [label="divide by zero\nlevel Error\ntests/contract_testcases/substrate/arrays/array_dimensions_04.sol:6:17-22"]
 	structs -> bar
 	structs -> bar
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/arrays/data_locations.sol" {
 strict digraph "tests/contract_testcases/substrate/arrays/data_locations.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations.sol:2:9-5:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations.sol:2:9-5:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations.sol:2:9-5:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations.sol:2:9-5:10"]
-	diagnostic_5 [label="data location 'storage' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations.sol:3:31-38"]
+	diagnostic_4 [label="data location 'storage' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations.sol:3:31-38"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_01.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/arrays/data_locations_01.sol" {
 strict digraph "tests/contract_testcases/substrate/arrays/data_locations_01.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_01.sol:2:9-5:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_01.sol:2:9-5:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_01.sol:2:9-5:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_01.sol:2:9-5:10"]
-	diagnostic_5 [label="data location 'calldata' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_01.sol:3:31-39"]
+	diagnostic_4 [label="data location 'calldata' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_01.sol:3:31-39"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_02.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/data_locations_02.sol"
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:2:9-6:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:2:9-6:10"]
-	diagnostic_7 [label="data location 'memory' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:4:31-37"]
+	diagnostic_6 [label="data location 'memory' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_02.sol:4:31-37"]
 	enums -> foo2
 	enums -> foo2
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_03.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/data_locations_03.sol"
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:2:9-6:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:2:9-6:10"]
-	diagnostic_7 [label="data location 'calldata' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:4:55-63"]
+	diagnostic_6 [label="data location 'calldata' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_03.sol:4:55-63"]
 	enums -> foo2
 	enums -> foo2
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_04.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/data_locations_04.sol"
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:2:9-6:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:2:9-6:10"]
-	diagnostic_7 [label="data location 'calldata' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:4:55-63"]
+	diagnostic_6 [label="data location 'calldata' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_04.sol:4:55-63"]
 	enums -> foo2
 	enums -> foo2
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_05.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/data_locations_05.sol"
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:2:9-6:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:2:9-6:10"]
-	diagnostic_7 [label="data location 'storage' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:4:54-61"]
+	diagnostic_6 [label="data location 'storage' can only be specified for array, struct or mapping\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_05.sol:4:54-61"]
 	enums -> foo2
 	enums -> foo2
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_06.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/data_locations_06.sol"
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:2:9-6:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:2:9-6:10"]
-	diagnostic_7 [label="parameter of type 'storage' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:4:34-41"]
+	diagnostic_6 [label="parameter of type 'storage' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_06.sol:4:34-41"]
 	enums -> foo2
 	enums -> foo2
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_07.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/data_locations_07.sol"
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:2:9-6:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:2:9-6:10"]
-	diagnostic_7 [label="return type of type 'storage' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:4:52-59"]
+	diagnostic_6 [label="return type of type 'storage' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_07.sol:4:52-59"]
 	enums -> foo2
 	enums -> foo2
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/arrays/data_locations_08.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/arrays/data_locations_08.sol"
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	foo2 [label="name: foo2\ncontract: foo\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:3:13-37\nvalue: bar1\nvalue: bar2"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:2:9-6:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:2:9-6:10"]
 	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:2:9-6:10"]
-	diagnostic_7 [label="return type of type 'storage' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:4:53-60"]
+	diagnostic_6 [label="return type of type 'storage' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/arrays/data_locations_08.sol:4:53-60"]
 	enums -> foo2
 	enums -> foo2
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/calls/payable_functions.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions.sol" {
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions.sol:2:9-6:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions.sol:2:9-6:10"]
-	diagnostic_5 [label="receive function must be declared external\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions.sol:3:13-29"]
+	diagnostic_4 [label="receive function must be declared external\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions.sol:3:13-29"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/calls/payable_functions_01.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions_01.sol" {
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions_01.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions_01.sol:2:9-6:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions_01.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions_01.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions_01.sol:2:9-6:10"]
-	diagnostic_5 [label="receive function must be declared payable\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions_01.sol:3:13-31"]
+	diagnostic_4 [label="receive function must be declared payable\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions_01.sol:3:13-31"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/calls/payable_functions_02.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions_02.sol" {
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions_02.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions_02.sol:2:9-6:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions_02.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions_02.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions_02.sol:2:9-6:10"]
-	diagnostic_5 [label="fallback function must not be declare payable, use 'receive() external payable' instead\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions_02.sol:3:13-40"]
+	diagnostic_4 [label="fallback function must not be declare payable, use 'receive() external payable' instead\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions_02.sol:3:13-40"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/calls/payable_functions_03.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions_03.sol" {
 strict digraph "tests/contract_testcases/substrate/calls/payable_functions_03.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions_03.sol:2:9-6:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/calls/payable_functions_03.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions_03.sol:2:9-6:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/calls/payable_functions_03.sol:2:9-6:10"]
-	diagnostic_5 [label="fallback function must be declared external\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions_03.sol:3:13-30"]
+	diagnostic_4 [label="fallback function must be declared external\nlevel Error\ntests/contract_testcases/substrate/calls/payable_functions_03.sol:3:13-30"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/contracts/contract_name.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/contracts/contract_name.sol" {
 strict digraph "tests/contract_testcases/substrate/contracts/contract_name.sol" {
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name.sol:1:1-3:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name.sol:1:1-3:10"]
-	diagnostic_5 [label="function cannot have same name as the contract\nlevel Error\ntests/contract_testcases/substrate/contracts/contract_name.sol:2:13-35"]
+	diagnostic_4 [label="function cannot have same name as the contract\nlevel Error\ntests/contract_testcases/substrate/contracts/contract_name.sol:2:13-35"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 3 - 3
tests/contract_testcases/substrate/contracts/contract_name_01.dot

@@ -2,11 +2,11 @@ strict digraph "tests/contract_testcases/substrate/contracts/contract_name_01.so
 	test [label="name: test\ncontract: test\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:2:13-27\nvalue: a"]
 	test [label="name: test\ncontract: test\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:2:13-27\nvalue: a"]
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:1:1-3:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:1:1-3:10"]
-	diagnostic_7 [label="test is already defined as a contract name\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:2:18-22"]
+	diagnostic_6 [label="test is already defined as a contract name\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:2:18-22"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:1:1-3:10"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/contracts/contract_name_01.sol:1:1-3:10"]
 	enums -> test
 	enums -> test
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Warning"]
-	diagnostic_7 -> note [label="note"]
+	diagnostics -> diagnostic_6 [label="Warning"]
+	diagnostic_6 -> note [label="note"]
 }
 }

+ 4 - 4
tests/contract_testcases/substrate/contracts/contract_name_02.dot

@@ -2,13 +2,13 @@ strict digraph "tests/contract_testcases/substrate/contracts/contract_name_02.so
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:1:1-3:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:1:1-3:10"]
 	var [label="variable test\nvisibility internal\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:2:13-22"]
 	var [label="variable test\nvisibility internal\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:2:13-22"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:1:1-3:10"]
-	diagnostic_6 [label="storage variable 'test' has never been used\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:2:13-22"]
-	diagnostic_7 [label="test is already defined as a contract name\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:2:18-22"]
+	diagnostic_5 [label="storage variable 'test' has never been used\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:2:13-22"]
+	diagnostic_6 [label="test is already defined as a contract name\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:2:18-22"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:1:1-3:10"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/contracts/contract_name_02.sol:1:1-3:10"]
 	contracts -> contract
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> var [label="variable"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_5 [label="Warning"]
 	diagnostics -> diagnostic_6 [label="Warning"]
 	diagnostics -> diagnostic_6 [label="Warning"]
-	diagnostics -> diagnostic_7 [label="Warning"]
-	diagnostic_7 -> note [label="note"]
+	diagnostic_6 -> note [label="note"]
 }
 }

+ 3 - 3
tests/contract_testcases/substrate/contracts/contract_name_03.dot

@@ -2,11 +2,11 @@ strict digraph "tests/contract_testcases/substrate/contracts/contract_name_03.so
 	test [label="name:test\ncontract: test\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:2:20-24\nfield name:a ty:bool"]
 	test [label="name:test\ncontract: test\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:2:20-24\nfield name:a ty:bool"]
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:1:1-3:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:1:1-3:10"]
-	diagnostic_7 [label="test is already defined as a contract name\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:2:20-24"]
+	diagnostic_6 [label="test is already defined as a contract name\nlevel Warning\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:2:20-24"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:1:1-3:10"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/contracts/contract_name_03.sol:1:1-3:10"]
 	structs -> test
 	structs -> test
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Warning"]
-	diagnostic_7 -> note [label="note"]
+	diagnostics -> diagnostic_6 [label="Warning"]
+	diagnostic_6 -> note [label="note"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/events/event_decl.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl.sol:3:19-22"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl.sol:3:19-22"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl.sol:2:9-4:10"]
-	diagnostic_7 [label="event 'foo' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl.sol:3:19-22"]
+	diagnostic_6 [label="event 'foo' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl.sol:3:19-22"]
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Warning"]
+	diagnostics -> diagnostic_6 [label="Warning"]
 }
 }

+ 5 - 5
tests/contract_testcases/substrate/events/event_decl_02.dot

@@ -3,14 +3,14 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_02.sol" {
 	e_3 [label="name:e\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_02.sol:4:19-20"]
 	e_3 [label="name:e\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_02.sol:4:19-20"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_02.sol:3:9-5:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_02.sol:3:9-5:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_02.sol:3:9-5:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_02.sol:3:9-5:10"]
-	diagnostic_9 [label="e is already defined as an enum\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_02.sol:4:19-20"]
+	diagnostic_8 [label="e is already defined as an enum\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_02.sol:4:19-20"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/events/event_decl_02.sol:2:14-15"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/events/event_decl_02.sol:2:14-15"]
-	diagnostic_11 [label="event 'e' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_02.sol:4:19-20"]
+	diagnostic_10 [label="event 'e' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_02.sol:4:19-20"]
 	enums -> e
 	enums -> e
 	events -> e_3
 	events -> e_3
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_9 [label="Warning"]
-	diagnostic_9 -> note [label="note"]
-	diagnostics -> diagnostic_11 [label="Warning"]
+	diagnostics -> diagnostic_8 [label="Warning"]
+	diagnostic_8 -> note [label="note"]
+	diagnostics -> diagnostic_10 [label="Warning"]
 }
 }

+ 3 - 3
tests/contract_testcases/substrate/events/event_decl_03.dot

@@ -2,11 +2,11 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_03.sol" {
 	e [label="name: e\ncontract: c\ntests/contract_testcases/substrate/events/event_decl_03.sol:3:13-26\nvalue: a1"]
 	e [label="name: e\ncontract: c\ntests/contract_testcases/substrate/events/event_decl_03.sol:3:13-26\nvalue: a1"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_03.sol:2:9-5:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_03.sol:2:9-5:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_03.sol:2:9-5:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_03.sol:2:9-5:10"]
-	diagnostic_7 [label="e is already defined as an enum\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_03.sol:4:19-20"]
+	diagnostic_6 [label="e is already defined as an enum\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_03.sol:4:19-20"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/events/event_decl_03.sol:3:18-19"]
 	note [label="location of previous definition\ntests/contract_testcases/substrate/events/event_decl_03.sol:3:18-19"]
 	enums -> e
 	enums -> e
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
-	diagnostic_7 -> note [label="note"]
+	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostic_6 -> note [label="note"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/events/event_decl_04.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_04.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_04.sol:3:19-22\nfield name:x ty:unresolved indexed:no"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_04.sol:3:19-22\nfield name:x ty:unresolved indexed:no"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_04.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_04.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_04.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_04.sol:2:9-4:10"]
-	diagnostic_7 [label="mapping type is not permitted as event field\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_04.sol:3:24-48"]
+	diagnostic_6 [label="mapping type is not permitted as event field\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_04.sol:3:24-48"]
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/events/event_decl_05.dot

@@ -3,10 +3,10 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_05.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_05.sol:7:19-22\nfield name:x ty:unresolved indexed:no"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_05.sol:7:19-22\nfield name:x ty:unresolved indexed:no"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_05.sol:6:9-8:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_05.sol:6:9-8:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_05.sol:6:9-8:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_05.sol:6:9-8:10"]
-	diagnostic_9 [label="mapping type is not permitted as event field\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_05.sol:7:24-27"]
+	diagnostic_8 [label="mapping type is not permitted as event field\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_05.sol:7:24-27"]
 	structs -> s
 	structs -> s
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_9 [label="Error"]
+	diagnostics -> diagnostic_8 [label="Error"]
 }
 }

+ 3 - 3
tests/contract_testcases/substrate/events/event_decl_06.dot

@@ -2,11 +2,11 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_06.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_06.sol:3:19-22\nfield name:x ty:bool indexed:no\nfield name:y ty:uint32 indexed:no"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_06.sol:3:19-22\nfield name:x ty:bool indexed:no\nfield name:y ty:uint32 indexed:no"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_06.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_06.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_06.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_06.sol:2:9-4:10"]
-	diagnostic_7 [label="event 'foo' has duplicate field name 'x'\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_06.sol:3:50-51"]
+	diagnostic_6 [label="event 'foo' has duplicate field name 'x'\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_06.sol:3:50-51"]
 	note [label="location of previous declaration of 'x'\ntests/contract_testcases/substrate/events/event_decl_06.sol:3:24-30"]
 	note [label="location of previous declaration of 'x'\ntests/contract_testcases/substrate/events/event_decl_06.sol:3:24-30"]
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
-	diagnostic_7 -> note [label="note"]
+	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostic_6 -> note [label="note"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/events/event_decl_07.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_07.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_07.sol:3:19-22\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes\nfield name:f4 ty:bool indexed:yes"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_07.sol:3:19-22\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes\nfield name:f4 ty:bool indexed:yes"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_07.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_07.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_07.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_07.sol:2:9-4:10"]
-	diagnostic_7 [label="event definition for 'foo' has 4 indexed fields where 3 permitted\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_07.sol:3:19-22"]
+	diagnostic_6 [label="event definition for 'foo' has 4 indexed fields where 3 permitted\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_07.sol:3:19-22"]
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/events/event_decl_08.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_08.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_08.sol:3:19-22\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_08.sol:3:19-22\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_08.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_08.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_08.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_08.sol:2:9-4:10"]
-	diagnostic_7 [label="event 'foo' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_08.sol:3:19-22"]
+	diagnostic_6 [label="event 'foo' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_08.sol:3:19-22"]
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Warning"]
+	diagnostics -> diagnostic_6 [label="Warning"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/events/event_decl_09.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_09.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_09.sol:3:19-22\nanonymous\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes\nfield name:f4 ty:bool indexed:yes\nfield name:f5 ty:bool indexed:yes"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_09.sol:3:19-22\nanonymous\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes\nfield name:f4 ty:bool indexed:yes\nfield name:f5 ty:bool indexed:yes"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_09.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_09.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_09.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_09.sol:2:9-4:10"]
-	diagnostic_7 [label="anonymous event definition for 'foo' has 5 indexed fields where 4 permitted\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_09.sol:3:19-22"]
+	diagnostic_6 [label="anonymous event definition for 'foo' has 5 indexed fields where 4 permitted\nlevel Error\ntests/contract_testcases/substrate/events/event_decl_09.sol:3:19-22"]
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/events/event_decl_10.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/events/event_decl_10.sol" {
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_10.sol:3:19-22\nanonymous\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes\nfield name:f4 ty:bool indexed:yes"]
 	foo [label="name:foo\ncontract: 0\ntests/contract_testcases/substrate/events/event_decl_10.sol:3:19-22\nanonymous\nfield name:f1 ty:bool indexed:yes\nfield name:f2 ty:bool indexed:yes\nfield name:f3 ty:bool indexed:yes\nfield name:f4 ty:bool indexed:yes"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_10.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/events/event_decl_10.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_10.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/events/event_decl_10.sol:2:9-4:10"]
-	diagnostic_7 [label="event 'foo' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_10.sol:3:19-22"]
+	diagnostic_6 [label="event 'foo' has never been emitted\nlevel Warning\ntests/contract_testcases/substrate/events/event_decl_10.sol:3:19-22"]
 	events -> foo
 	events -> foo
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Warning"]
+	diagnostics -> diagnostic_6 [label="Warning"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/function_types/decls_06.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/function_types/decls_06.sol" {
 strict digraph "tests/contract_testcases/substrate/function_types/decls_06.sol" {
 	contract [label="contract test\ntests/contract_testcases/substrate/function_types/decls_06.sol:1:1-4:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/function_types/decls_06.sol:1:1-4:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/function_types/decls_06.sol:1:1-4:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/function_types/decls_06.sol:1:1-4:10"]
-	diagnostic_5 [label="parameter of type 'function internal' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/function_types/decls_06.sol:2:26-72"]
+	diagnostic_4 [label="parameter of type 'function internal' not allowed public or external functions\nlevel Error\ntests/contract_testcases/substrate/function_types/decls_06.sol:2:26-72"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

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

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/function_types/decls_07.sol" {
 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-4:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/function_types/decls_07.sol:1:1-4:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/function_types/decls_07.sol:1:1-4:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/function_types/decls_07.sol:1:1-4:10"]
-	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"]
+	diagnostic_4 [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
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/function_types/decls_08.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/function_types/decls_08.sol" {
 strict digraph "tests/contract_testcases/substrate/function_types/decls_08.sol" {
 	contract [label="contract test\ntests/contract_testcases/substrate/function_types/decls_08.sol:1:1-3:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/function_types/decls_08.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/function_types/decls_08.sol:1:1-3:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/function_types/decls_08.sol:1:1-3:10"]
-	diagnostic_5 [label="variable of type internal function cannot be 'public'\nlevel Error\ntests/contract_testcases/substrate/function_types/decls_08.sol:2:13-66"]
+	diagnostic_4 [label="variable of type internal function cannot be 'public'\nlevel Error\ntests/contract_testcases/substrate/function_types/decls_08.sol:2:13-66"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 4 - 4
tests/contract_testcases/substrate/functions/payable.dot

@@ -3,12 +3,12 @@ strict digraph "tests/contract_testcases/substrate/functions/payable.sol" {
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable.sol:5:13-24"]
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable.sol:5:13-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable.sol:5:23-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable.sol:5:23-24"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable.sol:2:9-26"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable.sol:2:9-26"]
-	diagnostic_7 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable.sol:4:9-10:10"]
-	diagnostic_8 [label="internal or private function cannot be payable\nlevel Error\ntests/contract_testcases/substrate/functions/payable.sol:7:29-36"]
+	diagnostic_6 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable.sol:4:9-10:10"]
+	diagnostic_7 [label="internal or private function cannot be payable\nlevel Error\ntests/contract_testcases/substrate/functions/payable.sol:7:29-36"]
 	contracts -> contract
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
 	var -> number_literal [label="initializer"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Debug"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }
 }

+ 4 - 4
tests/contract_testcases/substrate/functions/payable_01.dot

@@ -3,12 +3,12 @@ strict digraph "tests/contract_testcases/substrate/functions/payable_01.sol" {
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable_01.sol:5:13-24"]
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable_01.sol:5:13-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable_01.sol:5:23-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable_01.sol:5:23-24"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_01.sol:2:9-26"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_01.sol:2:9-26"]
-	diagnostic_7 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_01.sol:4:9-10:10"]
-	diagnostic_8 [label="internal or private function cannot be payable\nlevel Error\ntests/contract_testcases/substrate/functions/payable_01.sol:7:29-36"]
+	diagnostic_6 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_01.sol:4:9-10:10"]
+	diagnostic_7 [label="internal or private function cannot be payable\nlevel Error\ntests/contract_testcases/substrate/functions/payable_01.sol:7:29-36"]
 	contracts -> contract
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
 	var -> number_literal [label="initializer"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Debug"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }
 }

+ 4 - 4
tests/contract_testcases/substrate/functions/payable_02.dot

@@ -3,12 +3,12 @@ strict digraph "tests/contract_testcases/substrate/functions/payable_02.sol" {
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable_02.sol:5:13-24"]
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable_02.sol:5:13-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable_02.sol:5:23-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable_02.sol:5:23-24"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_02.sol:2:9-26"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_02.sol:2:9-26"]
-	diagnostic_7 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_02.sol:4:9-10:10"]
-	diagnostic_8 [label="receive function must be declared payable\nlevel Error\ntests/contract_testcases/substrate/functions/payable_02.sol:7:13-31"]
+	diagnostic_6 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_02.sol:4:9-10:10"]
+	diagnostic_7 [label="receive function must be declared payable\nlevel Error\ntests/contract_testcases/substrate/functions/payable_02.sol:7:13-31"]
 	contracts -> contract
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
 	var -> number_literal [label="initializer"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Debug"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }
 }

+ 4 - 4
tests/contract_testcases/substrate/functions/payable_03.dot

@@ -3,12 +3,12 @@ strict digraph "tests/contract_testcases/substrate/functions/payable_03.sol" {
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable_03.sol:5:13-24"]
 	var [label="variable i\nvisibility internal\ntests/contract_testcases/substrate/functions/payable_03.sol:5:13-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable_03.sol:5:23-24"]
 	number_literal [label="int32 literal: 0\ntests/contract_testcases/substrate/functions/payable_03.sol:5:23-24"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_03.sol:2:9-26"]
 	diagnostic [label="pragma 'solidity' is ignored\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_03.sol:2:9-26"]
-	diagnostic_7 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_03.sol:4:9-10:10"]
-	diagnostic_8 [label="fallback function must not be declare payable, use 'receive() external payable' instead\nlevel Error\ntests/contract_testcases/substrate/functions/payable_03.sol:7:13-40"]
+	diagnostic_6 [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/functions/payable_03.sol:4:9-10:10"]
+	diagnostic_7 [label="fallback function must not be declare payable, use 'receive() external payable' instead\nlevel Error\ntests/contract_testcases/substrate/functions/payable_03.sol:7:13-40"]
 	contracts -> contract
 	contracts -> contract
 	contract -> var [label="variable"]
 	contract -> var [label="variable"]
 	var -> number_literal [label="initializer"]
 	var -> number_literal [label="initializer"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Debug"]
+	diagnostics -> diagnostic_7 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/functions/return_not_returns.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/functions/return_not_returns.sol" {
 strict digraph "tests/contract_testcases/substrate/functions/return_not_returns.sol" {
 	contract [label="contract test\ntests/contract_testcases/substrate/functions/return_not_returns.sol:1:1-5:10"]
 	contract [label="contract test\ntests/contract_testcases/substrate/functions/return_not_returns.sol:1:1-5:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/functions/return_not_returns.sol:1:1-5:10"]
 	diagnostic [label="found contract 'test'\nlevel Debug\ntests/contract_testcases/substrate/functions/return_not_returns.sol:1:1-5:10"]
-	diagnostic_5 [label="'return' unexpected. Did you mean 'returns'?\nlevel Error\ntests/contract_testcases/substrate/functions/return_not_returns.sol:2:40-46"]
+	diagnostic_4 [label="'return' unexpected. Did you mean 'returns'?\nlevel Error\ntests/contract_testcases/substrate/functions/return_not_returns.sol:2:40-46"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/functions/stray_semicolon_01.dot

@@ -2,9 +2,9 @@ strict digraph "tests/contract_testcases/substrate/functions/stray_semicolon_01.
 	a [label="name:a\ncontract: x\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:21-22\nfield name:f1 ty:uint32"]
 	a [label="name:a\ncontract: x\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:21-22\nfield name:f1 ty:uint32"]
 	contract [label="contract x\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:1-40"]
 	contract [label="contract x\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:1-40"]
 	diagnostic [label="found contract 'x'\nlevel Debug\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:1-40"]
 	diagnostic [label="found contract 'x'\nlevel Debug\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:1-40"]
-	diagnostic_7 [label="stray semicolon\nlevel Error\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:37-38"]
+	diagnostic_6 [label="stray semicolon\nlevel Error\ntests/contract_testcases/substrate/functions/stray_semicolon_01.sol:1:37-38"]
 	structs -> a
 	structs -> a
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 6 - 6
tests/contract_testcases/substrate/inheritance/inherit_types_03.dot

@@ -1,14 +1,14 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/inherit_types_03.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/inherit_types_03.sol" {
 	enum_x [label="name: enum_x\ncontract: b\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:9:13-35\nvalue: x1\nvalue: x2"]
 	enum_x [label="name: enum_x\ncontract: b\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:9:13-35\nvalue: x1\nvalue: x2"]
 	contract [label="contract a\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:2:9-6:10"]
 	contract [label="contract a\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:2:9-6:10"]
-	contract_5 [label="contract b\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:8:9-10:10"]
+	contract_4 [label="contract b\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:8:9-10:10"]
 	diagnostic [label="found contract 'a'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:2:9-6:10"]
 	diagnostic [label="found contract 'a'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:2:9-6:10"]
-	diagnostic_8 [label="type 'enum_x' not found\nlevel Error\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:3:45-51"]
-	diagnostic_9 [label="found contract 'b'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:8:9-10:10"]
+	diagnostic_7 [label="type 'enum_x' not found\nlevel Error\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:3:45-51"]
+	diagnostic_8 [label="found contract 'b'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/inherit_types_03.sol:8:9-10:10"]
 	enums -> enum_x
 	enums -> enum_x
 	contracts -> contract
 	contracts -> contract
-	contracts -> contract_5
+	contracts -> contract_4
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_8 [label="Error"]
-	diagnostics -> diagnostic_9 [label="Debug"]
+	diagnostics -> diagnostic_7 [label="Error"]
+	diagnostics -> diagnostic_8 [label="Debug"]
 }
 }

+ 4 - 4
tests/contract_testcases/substrate/inheritance/test_interface.dot

@@ -1,10 +1,10 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface.sol:2:9-5:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface.sol:2:9-5:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface.sol:2:9-5:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface.sol:2:9-5:10"]
-	diagnostic_5 [label="constructor not allowed in an interface\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface.sol:3:13-41"]
-	diagnostic_6 [label="'public': visibility for constructors is ignored\nlevel Warning\ntests/contract_testcases/substrate/inheritance/test_interface.sol:3:35-41"]
+	diagnostic_4 [label="constructor not allowed in an interface\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface.sol:3:13-41"]
+	diagnostic_5 [label="'public': visibility for constructors is ignored\nlevel Warning\ntests/contract_testcases/substrate/inheritance/test_interface.sol:3:35-41"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
-	diagnostics -> diagnostic_6 [label="Warning"]
+	diagnostics -> diagnostic_4 [label="Error"]
+	diagnostics -> diagnostic_5 [label="Warning"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/inheritance/test_interface_01.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_01.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_01.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface_01.sol:2:9-4:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface_01.sol:2:9-4:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_01.sol:2:9-4:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_01.sol:2:9-4:10"]
-	diagnostic_5 [label="function in an interface cannot have a body\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_01.sol:3:13-36"]
+	diagnostic_4 [label="function in an interface cannot have a body\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_01.sol:3:13-36"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 3 - 3
tests/contract_testcases/substrate/inheritance/test_interface_02.dot

@@ -1,10 +1,10 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_02.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_02.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:2:9-4:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:2:9-4:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:2:9-4:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:2:9-4:10"]
-	diagnostic_5 [label="function marked 'virtual' cannot also be 'private'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:3:13-35"]
-	diagnostic_6 [label="functions must be declared 'external' in an interface\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:3:13-35"]
+	diagnostic_4 [label="function marked 'virtual' cannot also be 'private'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:3:13-35"]
+	diagnostic_5 [label="functions must be declared 'external' in an interface\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_02.sol:3:13-35"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
+	diagnostics -> diagnostic_4 [label="Error"]
 	diagnostics -> diagnostic_5 [label="Error"]
 	diagnostics -> diagnostic_5 [label="Error"]
-	diagnostics -> diagnostic_6 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/inheritance/test_interface_03.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_03.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_03.sol" {
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface_03.sol:2:9-4:10"]
 	contract [label="contract foo\ntests/contract_testcases/substrate/inheritance/test_interface_03.sol:2:9-4:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_03.sol:2:9-4:10"]
 	diagnostic [label="found interface 'foo'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_03.sol:2:9-4:10"]
-	diagnostic_5 [label="functions must be declared 'external' in an interface\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_03.sol:3:13-36"]
+	diagnostic_4 [label="functions must be declared 'external' in an interface\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_03.sol:3:13-36"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/inheritance/test_interface_07.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_07.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_07.sol" {
 	contract [label="contract bar\ntests/contract_testcases/substrate/inheritance/test_interface_07.sol:2:9-4:10"]
 	contract [label="contract bar\ntests/contract_testcases/substrate/inheritance/test_interface_07.sol:2:9-4:10"]
 	diagnostic [label="found interface 'bar'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_07.sol:2:9-4:10"]
 	diagnostic [label="found interface 'bar'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_07.sol:2:9-4:10"]
-	diagnostic_5 [label="interface 'bar' is not allowed to have contract variable 'x'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_07.sol:3:13-18"]
+	diagnostic_4 [label="interface 'bar' is not allowed to have contract variable 'x'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_07.sol:3:13-18"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/inheritance/test_interface_08.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_08.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_interface_08.sol" {
 	contract [label="contract bar\ntests/contract_testcases/substrate/inheritance/test_interface_08.sol:2:9-4:10"]
 	contract [label="contract bar\ntests/contract_testcases/substrate/inheritance/test_interface_08.sol:2:9-4:10"]
 	diagnostic [label="found interface 'bar'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_08.sol:2:9-4:10"]
 	diagnostic [label="found interface 'bar'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_interface_08.sol:2:9-4:10"]
-	diagnostic_5 [label="interface 'bar' is not allowed to have contract variable 'x'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_08.sol:3:13-31"]
+	diagnostic_4 [label="interface 'bar' is not allowed to have contract variable 'x'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_interface_08.sol:3:13-31"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 3 - 3
tests/contract_testcases/substrate/inheritance/test_override.dot

@@ -1,10 +1,10 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_override.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_override.sol" {
 	contract [label="contract base\ntests/contract_testcases/substrate/inheritance/test_override.sol:2:9-6:10"]
 	contract [label="contract base\ntests/contract_testcases/substrate/inheritance/test_override.sol:2:9-6:10"]
 	diagnostic [label="found contract 'base'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_override.sol:2:9-6:10"]
 	diagnostic [label="found contract 'base'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_override.sol:2:9-6:10"]
-	diagnostic_5 [label="function redeclared 'override'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_override.sol:3:45-53"]
+	diagnostic_4 [label="function redeclared 'override'\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_override.sol:3:45-53"]
 	note [label="location of previous declaration of 'override'\ntests/contract_testcases/substrate/inheritance/test_override.sol:3:36-44"]
 	note [label="location of previous declaration of 'override'\ntests/contract_testcases/substrate/inheritance/test_override.sol:3:36-44"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
-	diagnostic_5 -> note [label="note"]
+	diagnostics -> diagnostic_4 [label="Error"]
+	diagnostic_4 -> note [label="note"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/inheritance/test_super.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_super.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_super.sol" {
 	contract [label="contract super\ntests/contract_testcases/substrate/inheritance/test_super.sol:1:1-18"]
 	contract [label="contract super\ntests/contract_testcases/substrate/inheritance/test_super.sol:1:1-18"]
 	diagnostic [label="found contract 'super'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_super.sol:1:1-18"]
 	diagnostic [label="found contract 'super'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_super.sol:1:1-18"]
-	diagnostic_5 [label="'super' shadows name of a builtin\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_super.sol:1:10-15"]
+	diagnostic_4 [label="'super' shadows name of a builtin\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_super.sol:1:10-15"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/inheritance/test_virtual.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/inheritance/test_virtual.sol" {
 strict digraph "tests/contract_testcases/substrate/inheritance/test_virtual.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/inheritance/test_virtual.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/inheritance/test_virtual.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_virtual.sol:2:9-4:10"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/substrate/inheritance/test_virtual.sol:2:9-4:10"]
-	diagnostic_5 [label="function with no body missing 'virtual'. This was permitted in older versions of the Solidity language, please update.\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_virtual.sol:3:13-35"]
+	diagnostic_4 [label="function with no body missing 'virtual'. This was permitted in older versions of the Solidity language, please update.\nlevel Error\ntests/contract_testcases/substrate/inheritance/test_virtual.sol:3:13-35"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/libraries/restrictions.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/libraries/restrictions.sol" {
 strict digraph "tests/contract_testcases/substrate/libraries/restrictions.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/libraries/restrictions.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/libraries/restrictions.sol:2:9-4:10"]
 	diagnostic [label="found library 'c'\nlevel Debug\ntests/contract_testcases/substrate/libraries/restrictions.sol:2:9-4:10"]
 	diagnostic [label="found library 'c'\nlevel Debug\ntests/contract_testcases/substrate/libraries/restrictions.sol:2:9-4:10"]
-	diagnostic_5 [label="constructor not allowed in a library\nlevel Error\ntests/contract_testcases/substrate/libraries/restrictions.sol:3:13-27"]
+	diagnostic_4 [label="constructor not allowed in a library\nlevel Error\ntests/contract_testcases/substrate/libraries/restrictions.sol:3:13-27"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/libraries/restrictions_01.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/libraries/restrictions_01.sol" {
 strict digraph "tests/contract_testcases/substrate/libraries/restrictions_01.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/libraries/restrictions_01.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/libraries/restrictions_01.sol:2:9-4:10"]
 	diagnostic [label="found library 'c'\nlevel Debug\ntests/contract_testcases/substrate/libraries/restrictions_01.sol:2:9-4:10"]
 	diagnostic [label="found library 'c'\nlevel Debug\ntests/contract_testcases/substrate/libraries/restrictions_01.sol:2:9-4:10"]
-	diagnostic_5 [label="receive not allowed in a library\nlevel Error\ntests/contract_testcases/substrate/libraries/restrictions_01.sol:3:13-31"]
+	diagnostic_4 [label="receive not allowed in a library\nlevel Error\ntests/contract_testcases/substrate/libraries/restrictions_01.sol:3:13-31"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

+ 2 - 2
tests/contract_testcases/substrate/libraries/restrictions_02.dot

@@ -1,8 +1,8 @@
 strict digraph "tests/contract_testcases/substrate/libraries/restrictions_02.sol" {
 strict digraph "tests/contract_testcases/substrate/libraries/restrictions_02.sol" {
 	contract [label="contract c\ntests/contract_testcases/substrate/libraries/restrictions_02.sol:2:9-4:10"]
 	contract [label="contract c\ntests/contract_testcases/substrate/libraries/restrictions_02.sol:2:9-4:10"]
 	diagnostic [label="found library 'c'\nlevel Debug\ntests/contract_testcases/substrate/libraries/restrictions_02.sol:2:9-4:10"]
 	diagnostic [label="found library 'c'\nlevel Debug\ntests/contract_testcases/substrate/libraries/restrictions_02.sol:2:9-4:10"]
-	diagnostic_5 [label="fallback not allowed in a library\nlevel Error\ntests/contract_testcases/substrate/libraries/restrictions_02.sol:3:13-32"]
+	diagnostic_4 [label="fallback not allowed in a library\nlevel Error\ntests/contract_testcases/substrate/libraries/restrictions_02.sol:3:13-32"]
 	contracts -> contract
 	contracts -> contract
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_5 [label="Error"]
+	diagnostics -> diagnostic_4 [label="Error"]
 }
 }

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