Mercurial > projects > dil
comparison trunk/src/dil/semantic/Pass1.d @ 798:c24be8d4f6ab
Added documentation comments.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sat, 01 Mar 2008 02:53:06 +0100 |
parents | 47c5099562c7 |
children |
comparison
equal
deleted
inserted
replaced
797:cf2ad5df025c | 798:c24be8d4f6ab |
---|---|
33 /// to the symbol tables of their respective scopes. | 33 /// to the symbol tables of their respective scopes. |
34 class SemanticPass1 : Visitor | 34 class SemanticPass1 : Visitor |
35 { | 35 { |
36 Scope scop; /// The current scope. | 36 Scope scop; /// The current scope. |
37 Module modul; /// The module to be semantically checked. | 37 Module modul; /// The module to be semantically checked. |
38 CompilationContext context; | 38 CompilationContext context; /// The compilation context. |
39 | 39 |
40 // Attributes: | 40 // Attributes: |
41 LinkageType linkageType; | 41 LinkageType linkageType; /// Current linkage type. |
42 Protection protection; | 42 Protection protection; /// Current protection attribute. |
43 StorageClass storageClass; | 43 StorageClass storageClass; /// Current storage classes. |
44 uint alignSize; | 44 uint alignSize; /// Current align size. |
45 | 45 |
46 /// Construct a SemanticPass1 object. | 46 /// Constructs a SemanticPass1 object. |
47 /// Params: | 47 /// Params: |
48 /// modul = the module to be processed. | 48 /// modul = the module to be processed. |
49 /// context = the compilation context. | |
49 this(Module modul, CompilationContext context) | 50 this(Module modul, CompilationContext context) |
50 { | 51 { |
51 this.modul = modul; | 52 this.modul = modul; |
52 this.context = new CompilationContext(context); | 53 this.context = new CompilationContext(context); |
53 this.alignSize = context.structAlign; | 54 this.alignSize = context.structAlign; |
54 } | 55 } |
55 | 56 |
56 /// Start semantic analysis. | 57 /// Starts processing the module. |
57 void start() | 58 void start() |
58 { | 59 { |
59 assert(modul.root !is null); | 60 assert(modul.root !is null); |
60 // Create module scope. | 61 // Create module scope. |
61 scop = new Scope(null, modul); | 62 scop = new Scope(null, modul); |
62 visit(modul.root); | 63 visit(modul.root); |
63 } | 64 } |
64 | 65 |
66 /// Enters a new scope. | |
65 void enterScope(ScopeSymbol s) | 67 void enterScope(ScopeSymbol s) |
66 { | 68 { |
67 scop = scop.enter(s); | 69 scop = scop.enter(s); |
68 } | 70 } |
69 | 71 |
72 /// Exits the current scope. | |
70 void exitScope() | 73 void exitScope() |
71 { | 74 { |
72 scop = scop.exit(); | 75 scop = scop.exit(); |
73 } | 76 } |
74 | 77 |
76 bool isModuleScope() | 79 bool isModuleScope() |
77 { | 80 { |
78 return scop.symbol.isModule(); | 81 return scop.symbol.isModule(); |
79 } | 82 } |
80 | 83 |
81 /// Insert a symbol into the current scope. | 84 /// Inserts a symbol into the current scope. |
82 void insert(Symbol symbol, Identifier* name) | 85 void insert(Symbol symbol, Identifier* name) |
83 { | 86 { |
84 auto symX = scop.symbol.lookup(name); | 87 auto symX = scop.symbol.lookup(name); |
85 if (symX) | 88 if (symX) |
86 reportSymbolConflict(symbol, symX, name); | 89 reportSymbolConflict(symbol, symX, name); |
88 scop.symbol.insert(symbol, name); | 91 scop.symbol.insert(symbol, name); |
89 // Set the current scope symbol as the parent. | 92 // Set the current scope symbol as the parent. |
90 symbol.parent = scop.symbol; | 93 symbol.parent = scop.symbol; |
91 } | 94 } |
92 | 95 |
93 /// Insert a symbol into scopeSym. | 96 /// Inserts a symbol into scopeSym. |
94 void insert(Symbol symbol, ScopeSymbol scopeSym) | 97 void insert(Symbol symbol, ScopeSymbol scopeSym) |
95 { | 98 { |
96 auto symX = scopeSym.lookup(symbol.name); | 99 auto symX = scopeSym.lookup(symbol.name); |
97 if (symX) | 100 if (symX) |
98 reportSymbolConflict(symbol, symX, symbol.name); | 101 reportSymbolConflict(symbol, symX, symbol.name); |
100 scopeSym.insert(symbol, symbol.name); | 103 scopeSym.insert(symbol, symbol.name); |
101 // Set the current scope symbol as the parent. | 104 // Set the current scope symbol as the parent. |
102 symbol.parent = scopeSym; | 105 symbol.parent = scopeSym; |
103 } | 106 } |
104 | 107 |
105 /// Insert a symbol, overloading on the name, into the current scope. | 108 /// Inserts a symbol, overloading on the name, into the current scope. |
106 void insertOverload(Symbol sym, Identifier* name) | 109 void insertOverload(Symbol sym, Identifier* name) |
107 { | 110 { |
108 auto sym2 = scop.symbol.lookup(name); | 111 auto sym2 = scop.symbol.lookup(name); |
109 if (sym2) | 112 if (sym2) |
110 { | 113 { |
118 scop.symbol.insert(new OverloadSet(name, sym.node), name); | 121 scop.symbol.insert(new OverloadSet(name, sym.node), name); |
119 // Set the current scope symbol as the parent. | 122 // Set the current scope symbol as the parent. |
120 sym.parent = scop.symbol; | 123 sym.parent = scop.symbol; |
121 } | 124 } |
122 | 125 |
123 /// Report error: new symbol s1 conflicts with existing symbol s2. | 126 /// Reports an error: new symbol s1 conflicts with existing symbol s2. |
124 void reportSymbolConflict(Symbol s1, Symbol s2, Identifier* name) | 127 void reportSymbolConflict(Symbol s1, Symbol s2, Identifier* name) |
125 { | 128 { |
126 auto loc = s2.node.begin.getErrorLocation(); | 129 auto loc = s2.node.begin.getErrorLocation(); |
127 auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum); | 130 auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum); |
128 error(s1.node.begin, MSG.DeclConflictsWithDecl, name.str, locString); | 131 error(s1.node.begin, MSG.DeclConflictsWithDecl, name.str, locString); |
129 } | 132 } |
130 | 133 |
134 /// Creates an error report. | |
131 void error(Token* token, char[] formatMsg, ...) | 135 void error(Token* token, char[] formatMsg, ...) |
132 { | 136 { |
133 if (!modul.infoMan) | 137 if (!modul.infoMan) |
134 return; | 138 return; |
135 auto location = token.getErrorLocation(); | 139 auto location = token.getErrorLocation(); |
136 auto msg = Format(_arguments, _argptr, formatMsg); | 140 auto msg = Format(_arguments, _argptr, formatMsg); |
137 modul.infoMan ~= new SemanticError(location, msg); | 141 modul.infoMan ~= new SemanticError(location, msg); |
138 } | 142 } |
139 | 143 |
140 | 144 |
145 /// Collects info about nodes which have to be evaluated later. | |
141 static class Deferred | 146 static class Deferred |
142 { | 147 { |
143 Node node; | 148 Node node; |
144 ScopeSymbol symbol; | 149 ScopeSymbol symbol; |
145 // Saved attributes. | 150 // Saved attributes. |
147 Protection protection; | 152 Protection protection; |
148 StorageClass storageClass; | 153 StorageClass storageClass; |
149 uint alignSize; | 154 uint alignSize; |
150 } | 155 } |
151 | 156 |
152 // List of mixin, static if, static assert and pragma(msg,...) declarations. | 157 /// List of mixin, static if, static assert and pragma(msg,...) declarations. |
153 // Their analysis must be deferred because they entail | 158 /// |
154 // evaluation of expressions. | 159 /// Their analysis must be deferred because they entail |
160 /// evaluation of expressions. | |
155 Deferred[] deferred; | 161 Deferred[] deferred; |
156 | 162 |
163 /// Adds a deferred node to the list. | |
157 void addDeferred(Node node) | 164 void addDeferred(Node node) |
158 { | 165 { |
159 auto d = new Deferred; | 166 auto d = new Deferred; |
160 d.node = node; | 167 d.node = node; |
161 d.symbol = scop.symbol; | 168 d.symbol = scop.symbol; |
164 d.storageClass = storageClass; | 171 d.storageClass = storageClass; |
165 d.alignSize = alignSize; | 172 d.alignSize = alignSize; |
166 deferred ~= d; | 173 deferred ~= d; |
167 } | 174 } |
168 | 175 |
169 private alias Declaration D; | 176 private alias Declaration D; /// A handy alias. Saves typing. |
170 | 177 |
171 override | 178 override |
172 { | 179 { |
173 D visit(CompoundDeclaration d) | 180 D visit(CompoundDeclaration d) |
174 { | 181 { |