It builds the set of type and other constraints that must be fulfilled for the program to be valid.
It uses a constraint solver to solve the set of constraints and generate a program that satisfies them.
IE For "List list" to work, there must be a thing named List available as a typedef.
For list = 0 to work, tlist must be a pointer or an int.
For list->data to work, list must be a pointer to a struct, and that struct must have a member named data.
for list->data = val to work, the member named data must be compatible with a double.
It simply generates all of the constraints like this on the program, and then solves the constraint set, which produces a valid program (hopefully. it is possible it may not have enough data in some cases, given how C is parsed)
Exactly. Some programs are inherently ambiguous. In such cases, we cannot do much.
- Example 1: `void f(){x * y;}`
It's impossible to know whether that is a multiplication or pointer declaration.
- Example 2: `void f(){x y = 0;}`
We can only know that x is a scalar type (in C terminology), but it could be an int, int * , int * * , etc.