.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

116 lines
3.9 KiB

Compiler operation
The compiler has a number of phases:
* Parsing.
Initially the compiler parses all the source files and keeps a
parsed representation in memory. Very syntax error checking
is performed at this point.
The compiler stores the information in classes whose names
represent the language construct, for example, the "if"
construct is stored in an `If' class. A class is stored in a
`Class'.
* The TypeManager
The TypeManager loads all the assemblies that were referenced
by the programmer. The CLR type system is used as our
repository for types defined as well.
So the same interface that is used to query the types,
properties and flags about system types is the same interface
that we use for our types.
As we work our way through the code generation and semantic
analysis, new types are entered into the Type system through
the use of System.Reflection.Emit. The TypeManager will
lookup types on both the user defined types and on the system
defined ones.
So special care has to be used. The order in which we
proceeed from here is important.
* Base class resolution and type definition.
Once the parsing has happened, the compiler resolves the
inheritance tree for interfaces. This is done recursively
and we catch recursive interface definitions here.
After this is done, we continue on with classes. Classes have
can have an optional "parent" inherit from or the implicit
System.Object class (for normal builds, builds with /nostdlib
will allow you to compile class System.Object with no parent).
At this point we do some error checking and verify that the
inherits/implements section of a class is correct (since we
have previously built the interface inheritance).
By the time we are done, all classes, structs and interfaces
have been created using System.Reflection.Emit and registered
with the Type Manager.
This allows us to define fields and resolve argument names for
methods, properties, indexers and events.
* Field generation
Fields are generated next, we go through all the type
containers (classes and structs) and enter the fields into
their types.
* Method, Properties, Indexers and events definitions
Now all the methods, constructors, properties, indexers and
events are entered. They are only `defined' using
System.Reflection.Emit. No code generation will happen until
everything has been entered into System.Reflection.Emit.
This is important because to actually generate code we need to
know everything about the environment in which the code is
being generated.
* Code Generation
At this point all the definitions have been entered into the
type manager through System.Reflection.Emit. We can now use
System.Reflection to query all the information about the
types.
Your normal semantic analysis and code generation phase lives
here.
* Statements
Most of the statements are handled in the codegen.cs file.
* Expressions
* Error reporting
Always use `Report::Error' or `Report::Warning' methods of Report
class. The actual Report instance is available via local context.
An expression error reporting has to be done during Resolve phase,
except when it's Emit specific (very rare).
Error reporting should try to use the same codes that the
Microsoft compiler uses (if only so we can track which errors
we handle and which ones we dont).
If there is an error which is specific to MSC, use negative
numbers, and register the number in mcs/errors/errors.txt
Try to write a test case for any error that you run into the
code of the compiler if there is none already.
Put your test case in a file called csNNNN.cs in the
mcs/errors directory, and have the first two lines be:
// csNNNN.cs: This is the error message
// Line: XXX
// Compiler options: an optional compiler options
Where `XXX' is the line where the error ocurrs. We will later
use this as a regression test suite for catching errors in the
compiler.