It's not exactly clear what's going on in your example. If you're building data production-line style, you'd typically have something like this, passing by reference:
DataStruct d;
step1(d);
step2(d);
step3(d);
step4(d);
step5(d);
In terms of understanding which stage contributes which field(s) to the structure, in the trivial case it might be just easier to inspect the code within each method, but if there is need for real organisation and clarity, then typically you'd start to reflect it in the naming scheme of the fields, or in the definition of multiple structures that represent the final structure in different stages of production.
So with a naming scheme, you might have:
struct DataStruct {
int S1Field1;
int S1Field2;
int S1Field3;
int S2Field4;
int S3Field5;
(etc.)
}
...with the prefix representing the stage at which that field is built.
If that's insufficient for whatever reason, then you can start defining separate structures:
struct DataStructBuild1 {
int Field1; //new
int Field2; //new
int Field3; //new
}
struct DataStructBuild2 {
int Field1; //from Build 1
int Field2; //from Build 1
int Field3; //from Build 1
int Field4; //new
}
(etc.)
DataStructBuild1 d1;
DataStructBuild2 d2;
DataStructBuild3 d3;
step1(d1);
step2(d1, out d2);
step3(d2, out d3);
(etc.)
Clearly with this latter approach, it's impossible for earlier steps to refer to fields that aren't built yet, because the structure they are passed to modify does not contain any unbuilt fields - it contains only the available inputs and the receptacles for the output of the given stage.
It might also be useful to use a combination of both approaches - separate structures for each state, and a naming prefix to represent the stage at which those fields become available - if the number of fields is large and there is a desire to keep careful track of which fields are already built and which are being built.
And if necessary, you can define a final structure that contains a clean naming scheme free of the prefixes, which are only added as scaffolding for better understanding in the context of the building process, but which don't need to be preserved into other parts of the program later.
I should add one final remark, @Christophe's answer involving OOP would be more appropriate where the building stage for the data is so large or complicated that it would be somehow under the purview of multiple programming teams (or at least multiple individuals who have separate areas of concern), and there needs to be a system of getters and setters defining an interface between the realms of the two teams, exceptions to ensure that people who didn't write the code and aren't familiar with it's innards are warned when they aren't using it properly, and so on.
When you're not working at the interface between two teams, but working entirely within your own scope, OOP is usually a very complicated and heavyweight approach to solving problems.