Repository: Qiskit/qiskit

Issue:
qasm3 exporter wrong placement of `input` declaration
### Environment

- **Qiskit Terra version**: 0.20.0
- **Python version**: 3.8.13
- **Operating system**: macOS Monterey 12.3.1


### What is happening?

When exporting parametrized `QuantumCircuit`s with custom gates to a QASM3 string, the exporter wrongly places the circuit's `input` declaration after the `gate` declarations, which is not according to the OpenQASM3.0 grammar - IO declarations should appear in the [header](https://github.com/Qiskit/openqasm/blob/c39eac9f5c87b80df9e8eaeced96cbf4b477e5d2/source/grammar/qasm3.g4#L12).

### How can we reproduce the issue?

Run the following:

```python
from qiskit import QuantumCircuit, qasm3
from qiskit.circuit import Parameter

theta = Parameter("theta")
inner_qc = QuantumCircuit(1)
inner_qc.rz(theta, 0)
qc = QuantumCircuit(1)
qc.append(inner_qc.to_gate(), range(1))
print(qasm3.dumps(qc))
```
The resulting OpenQASM3.0 code is then:
```qasm
OPENQASM 3;
include "stdgates.inc";
gate circuit_21(theta) _gate_q_0 {
  rz(theta) _gate_q_0;
}
input float[64] theta;
qubit[1] _all_qubits;
let q = _all_qubits[0:0];
circuit_21(theta) q[0];
```

### What should happen?

The expected output according to the grammar is:
```qasm
OPENQASM 3;
include "stdgates.inc";
input float[64] theta;
gate circuit_21(theta) _gate_q_0 {
  rz(theta) _gate_q_0;
}
qubit[1] _all_qubits;
let q = _all_qubits[0:0];
circuit_21(theta) q[0];
```

### Any suggestions?

_No response_


Discussion:
Thanks for the report!  I'll fix this in the Terra exporter, though we've just missed the window to get it into Terra 0.20.1 that should release later today.  I'll target it for 0.20.2 in 2-3 weeks' time.

It's a bit questionable why the current reference grammar forbids this ordering of `input` and `gate` statements (I'm not sure any actual implementations have the same restriction), but it's a bug that Terra doesn't use the order that currently works in the reference grammar.

Resolving patch:
diff --git a/qiskit/qasm3/exporter.py b/qiskit/qasm3/exporter.py
--- a/qiskit/qasm3/exporter.py
+++ b/qiskit/qasm3/exporter.py
@@ -532,9 +532,9 @@ def build_global_statements(self) -> List[ast.Statement]:
         return [
             statement
             for source in (
-                definitions,
                 inputs,
                 outputs,
+                definitions,
                 variables,
                 bit_declarations,
                 quantum_declarations,


Test patch:
diff --git a/test/python/circuit/test_circuit_qasm3.py b/test/python/circuit/test_circuit_qasm3.py
--- a/test/python/circuit/test_circuit_qasm3.py
+++ b/test/python/circuit/test_circuit_qasm3.py
@@ -368,10 +368,10 @@ def test_custom_gate_with_unbound_parameter(self):
             [
                 "OPENQASM 3;",
                 'include "stdgates.inc";',
+                "input float[64] a;",
                 "gate custom(a) _gate_q_0 {",
                 "  rx(a) _gate_q_0;",
                 "}",
-                "input float[64] a;",
                 "qubit[1] _all_qubits;",
                 "let q = _all_qubits[0:0];",
                 "custom(a) q[0];",
@@ -504,6 +504,8 @@ def test_unknown_parameterized_gate_called_multiple_times(self):
         expected_qasm = "\n".join(
             [
                 "OPENQASM 3;",
+                "input float[64] x;",
+                "input float[64] y;",
                 "gate rzx(x) _gate_q_0, _gate_q_1 {",
                 "  h _gate_q_1;",
                 "  cx _gate_q_0, _gate_q_1;",
@@ -511,8 +513,6 @@ def test_unknown_parameterized_gate_called_multiple_times(self):
                 "  cx _gate_q_0, _gate_q_1;",
                 "  h _gate_q_1;",
                 "}",
-                "input float[64] x;",
-                "input float[64] y;",
                 "qubit[2] _all_qubits;",
                 "let q = _all_qubits[0:1];",
                 "rzx(x) q[0], q[1];",