I'm writing a compiler for a simple c-like language. I'm trying to do analysis for the following example:
struct Foo {
char* name;
};
struct Foo foo;
char* blah = foo.name;
Specifically, this analysis will handle if foo
is unresolved, or if name
is unresolved, etc.
The two ways I approach this is with name resolution, i.e. making sure that foo
exists, and name
exists in foo
. Then there is 'type resolution', which is where I make sure that the Foo
structure exists.
First question:
- Am I getting this right that the type resolution pass would check if the "Foo" structure exists?
I ask this because I have a slight issue with this approach. Because name resolution is done before type resolution, we can't check foo.name
because the structure Foo
has not been resolved yet, so we know nothing about the type, it's fields, their types, etc.
If this is a case that is handled in type resolution:
- Do I do type resolution before or after name resolution?
If I do name resolution before type resolution:
- How do I approach my problem where I need to know about the type in name resolution?
An approach I've taken in the past is to merge type resolution with scope resolution into a single pass.
You'll need to build up two environments/tables (one with types and one with names).
so at
char* blah = foo.name
, you'd havefoo
in your name table with a type ofFoo
, in your type table, you'd haveFoo
as a struct with fieldname
. Then you can check that your field accessfoo.name
is valid (which means both thatfoo
is declared andfoo
has a type with.name
as a field).