2009-12-12 Rodrigo Kumpera <rkumpera@novell.com>
[mcs.git] / mcs / compiler.doc
blob952437601c0800e97b3c4d2767e05f2779a26993
1 Compiler operation
3 The compiler has a number of phases:
5 * Parsing.
7         Initially the compiler parses all the source files and keeps a
8         parsed representation in memory.  Very syntax error checking
9         is performed at this point.
11         The compiler stores the information in classes whose names
12         represent the language construct, for example, the "if"
13         construct is stored in an `If' class.  A class is stored in a
14         `Class'.
16 * The TypeManager
18         The TypeManager loads all the assemblies that were referenced
19         by the programmer.  The CLR type system is used as our
20         repository for types defined as well.
22         So the same interface that is used to query the types,
23         properties and flags about system types is the same interface
24         that we use for our types.
26         As we work our way through the code generation and semantic
27         analysis, new types are entered into the Type system through
28         the use of System.Reflection.Emit.  The TypeManager will
29         lookup types on both the user defined types and on the system
30         defined ones.
32         So special care has to be used.  The order in which we
33         proceeed from here is important. 
35 * Base class resolution and type definition.
37         Once the parsing has happened, the compiler resolves the
38         inheritance tree for interfaces.   This is done recursively
39         and we catch recursive interface definitions here.
41         After this is done, we continue on with classes.  Classes have
42         can have an optional "parent" inherit from or the implicit
43         System.Object class (for normal builds, builds with /nostdlib
44         will allow you to compile class System.Object with no parent).
46         At this point we do some error checking and verify that the
47         inherits/implements section of a class is correct (since we
48         have previously built the interface inheritance).
50         By the time we are done, all classes, structs and interfaces
51         have been created using System.Reflection.Emit and registered
52         with the Type Manager.
54         This allows us to define fields and resolve argument names for
55         methods, properties, indexers and events. 
57 * Field generation
59         Fields are generated next, we go through all the type
60         containers (classes and structs) and enter the fields into
61         their types.
63 * Method, Properties, Indexers and events definitions
65         Now all the methods, constructors, properties, indexers and
66         events are entered.  They are only `defined' using
67         System.Reflection.Emit.  No code generation will happen until
68         everything has been entered into System.Reflection.Emit.
70         This is important because to actually generate code we need to
71         know everything about the environment in which the code is
72         being generated.
74 * Code Generation
76         At this point all the definitions have been entered into the
77         type manager through System.Reflection.Emit.  We can now use
78         System.Reflection to query all the information about the
79         types. 
81         Your normal semantic analysis and code generation phase lives
82         here.
84 * Statements
86         Most of the statements are handled in the codegen.cs file.
88 * Expressions
90 * Error reporting
92         Always use `Report::Error' or `Report::Warning' methods of Report
93         class. The actual Report instance is available via local context.
94         An expression error reporting has to be done during Resolve phase,
95         except when it's Emit specific (very rare).
97         Error reporting should try to use the same codes that the
98         Microsoft compiler uses (if only so we can track which errors
99         we handle and which ones we dont).
101         If there is an error which is specific to MSC, use negative
102         numbers, and register the number in mcs/errors/errors.txt
104         Try to write a test case for any error that you run into the
105         code of the compiler if there is none already.
107         Put your test case in a file called csNNNN.cs in the
108         mcs/errors directory, and have the first two lines be:
110         // csNNNN.cs: This is the error message
111         // Line: XXX
112         // Compiler options: an optional compiler options
114         Where `XXX' is the line where the error ocurrs.  We will later
115         use this as a regression test suite for catching errors in the
116         compiler.