/src/solidity/libsolidity/ast/ASTAnnotations.h
Line | Count | Source |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * @author Christian <c@ethdev.com> |
20 | | * @date 2015 |
21 | | * Object containing the type and other annotations for the AST nodes. |
22 | | */ |
23 | | |
24 | | #pragma once |
25 | | |
26 | | #include <libsolidity/ast/ASTForward.h> |
27 | | #include <libsolidity/ast/ASTEnums.h> |
28 | | #include <libsolidity/ast/ExperimentalFeatures.h> |
29 | | |
30 | | #include <libsolutil/Numeric.h> |
31 | | #include <libsolutil/SetOnce.h> |
32 | | |
33 | | #include <map> |
34 | | #include <memory> |
35 | | #include <optional> |
36 | | #include <set> |
37 | | #include <vector> |
38 | | |
39 | | namespace solidity::yul |
40 | | { |
41 | | struct AsmAnalysisInfo; |
42 | | struct Identifier; |
43 | | class Dialect; |
44 | | } |
45 | | |
46 | | namespace solidity::frontend |
47 | | { |
48 | | |
49 | | class Type; |
50 | | class ArrayType; |
51 | | |
52 | | struct CallGraph; |
53 | | |
54 | | struct ASTAnnotation |
55 | | { |
56 | 1.87M | ASTAnnotation() = default; |
57 | | |
58 | | ASTAnnotation(ASTAnnotation const&) = delete; |
59 | | ASTAnnotation(ASTAnnotation&&) = delete; |
60 | | |
61 | | ASTAnnotation& operator=(ASTAnnotation const&) = delete; |
62 | | ASTAnnotation& operator=(ASTAnnotation&&) = delete; |
63 | | |
64 | 1.87M | virtual ~ASTAnnotation() = default; |
65 | | }; |
66 | | |
67 | | struct DocTag |
68 | | { |
69 | | std::string content; ///< The text content of the tag. |
70 | | std::string paramName; ///< Only used for @param, stores the parameter name. |
71 | | }; |
72 | | |
73 | | struct StructurallyDocumentedAnnotation |
74 | | { |
75 | 168k | StructurallyDocumentedAnnotation() = default; |
76 | | |
77 | | StructurallyDocumentedAnnotation(StructurallyDocumentedAnnotation const&) = delete; |
78 | | StructurallyDocumentedAnnotation(StructurallyDocumentedAnnotation&&) = delete; |
79 | | |
80 | | StructurallyDocumentedAnnotation& operator=(StructurallyDocumentedAnnotation const&) = delete; |
81 | | StructurallyDocumentedAnnotation& operator=(StructurallyDocumentedAnnotation&&) = delete; |
82 | | |
83 | 168k | virtual ~StructurallyDocumentedAnnotation() = default; |
84 | | |
85 | | /// Mapping docstring tag name -> content. |
86 | | std::multimap<std::string, DocTag> docTags; |
87 | | /// contract that @inheritdoc references if it exists |
88 | | ContractDefinition const* inheritdocReference = nullptr; |
89 | | }; |
90 | | |
91 | | struct SourceUnitAnnotation: ASTAnnotation |
92 | | { |
93 | | /// The "absolute" (in the compiler sense) path of this source unit. |
94 | | util::SetOnce<std::string> path; |
95 | | /// The exported symbols (all global symbols). |
96 | | util::SetOnce<std::map<ASTString, std::vector<Declaration const*>>> exportedSymbols; |
97 | | /// Experimental features. |
98 | | std::set<ExperimentalFeature> experimentalFeatures; |
99 | | /// Using the new ABI coder. Set to `false` if using ABI coder v1. |
100 | | util::SetOnce<bool> useABICoderV2; |
101 | | }; |
102 | | |
103 | | struct ScopableAnnotation |
104 | | { |
105 | 278k | ScopableAnnotation() = default; |
106 | | |
107 | | ScopableAnnotation(ScopableAnnotation const&) = delete; |
108 | | ScopableAnnotation(ScopableAnnotation&&) = delete; |
109 | | |
110 | | ScopableAnnotation& operator=(ScopableAnnotation const&) = delete; |
111 | | ScopableAnnotation& operator=(ScopableAnnotation&&) = delete; |
112 | | |
113 | 278k | virtual ~ScopableAnnotation() = default; |
114 | | |
115 | | /// The scope this declaration resides in. Can be nullptr if it is the global scope. |
116 | | /// Filled by the Scoper. |
117 | | ASTNode const* scope = nullptr; |
118 | | /// Pointer to the contract this declaration resides in. Can be nullptr if the current scope |
119 | | /// is not part of a contract. Filled by the Scoper. |
120 | | ContractDefinition const* contract = nullptr; |
121 | | }; |
122 | | |
123 | | struct DeclarationAnnotation: ASTAnnotation, ScopableAnnotation |
124 | | { |
125 | | }; |
126 | | |
127 | | struct ImportAnnotation: DeclarationAnnotation |
128 | | { |
129 | | /// The absolute path of the source unit to import. |
130 | | util::SetOnce<std::string> absolutePath; |
131 | | /// The actual source unit. |
132 | | SourceUnit const* sourceUnit = nullptr; |
133 | | }; |
134 | | |
135 | | struct TypeDeclarationAnnotation: DeclarationAnnotation |
136 | | { |
137 | | /// The name of this type, prefixed by proper namespaces if globally accessible. |
138 | | util::SetOnce<std::string> canonicalName; |
139 | | }; |
140 | | |
141 | | struct StructDeclarationAnnotation: TypeDeclarationAnnotation |
142 | | { |
143 | | /// Whether the struct is recursive, i.e. if the struct (recursively) contains a member that involves a struct of the same |
144 | | /// type, either in a dynamic array, as member of another struct or inside a mapping. |
145 | | /// Only cases in which the recursive occurrence is within a dynamic array or a mapping are valid, while direct |
146 | | /// recursion immediately raises an error. |
147 | | /// Will be filled in by the DeclarationTypeChecker. |
148 | | std::optional<bool> recursive; |
149 | | /// Whether the struct contains a mapping type, either directly or, indirectly inside another |
150 | | /// struct or an array. |
151 | | std::optional<bool> containsNestedMapping; |
152 | | }; |
153 | | |
154 | | struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocumentedAnnotation |
155 | | { |
156 | | /// List of functions and modifiers without a body. Can also contain functions from base classes. |
157 | | std::optional<std::vector<Declaration const*>> unimplementedDeclarations; |
158 | | /// List of all (direct and indirect) base contracts in order from derived to |
159 | | /// base, including the contract itself. |
160 | | std::vector<ContractDefinition const*> linearizedBaseContracts; |
161 | | /// Mapping containing the nodes that define the arguments for base constructors. |
162 | | /// These can either be inheritance specifiers or modifier invocations. |
163 | | std::map<FunctionDefinition const*, ASTNode const*> baseConstructorArguments; |
164 | | /// A graph with edges representing calls between functions that may happen during contract construction. |
165 | | util::SetOnce<std::shared_ptr<CallGraph const>> creationCallGraph; |
166 | | /// A graph with edges representing calls between functions that may happen in a deployed contract. |
167 | | util::SetOnce<std::shared_ptr<CallGraph const>> deployedCallGraph; |
168 | | |
169 | | /// List of contracts whose bytecode is referenced by this contract, e.g. through "new". |
170 | | /// The Value represents the ast node that referenced the contract. |
171 | | std::map<ContractDefinition const*, ASTNode const*, ASTCompareByID<ContractDefinition>> contractDependencies; |
172 | | |
173 | | // Per-contract map from function AST IDs to internal dispatch function IDs. |
174 | | std::map<FunctionDefinition const*, uint64_t> internalFunctionIDs; |
175 | | }; |
176 | | |
177 | | struct StorageLayoutSpecifierAnnotation: ASTAnnotation |
178 | | { |
179 | | // The evaluated value of the expression specifying the contract storage layout base |
180 | | util::SetOnce<u256> baseSlot; |
181 | | }; |
182 | | |
183 | | struct CallableDeclarationAnnotation: DeclarationAnnotation |
184 | | { |
185 | | /// The set of functions/modifiers/events this callable overrides. |
186 | | std::set<CallableDeclaration const*> baseFunctions; |
187 | | }; |
188 | | |
189 | | struct FunctionDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation |
190 | | { |
191 | | }; |
192 | | |
193 | | struct EventDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation |
194 | | { |
195 | | }; |
196 | | |
197 | | struct ErrorDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation |
198 | | { |
199 | | }; |
200 | | |
201 | | |
202 | | struct ModifierDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation |
203 | | { |
204 | | }; |
205 | | |
206 | | struct VariableDeclarationAnnotation: DeclarationAnnotation, StructurallyDocumentedAnnotation |
207 | | { |
208 | | /// Type of variable (type of identifier referencing this variable). |
209 | | Type const* type = nullptr; |
210 | | /// The set of functions this (public state) variable overrides. |
211 | | std::set<CallableDeclaration const*> baseFunctions; |
212 | | }; |
213 | | |
214 | | struct StatementAnnotation: ASTAnnotation |
215 | | { |
216 | | }; |
217 | | |
218 | | struct InlineAssemblyAnnotation: StatementAnnotation |
219 | | { |
220 | | struct ExternalIdentifierInfo |
221 | | { |
222 | | Declaration const* declaration = nullptr; |
223 | | /// Suffix used, one of "slot", "offset", "length", "address", "selector" or empty. |
224 | | std::string suffix; |
225 | | size_t valueSize = size_t(-1); |
226 | | }; |
227 | | |
228 | | /// Mapping containing resolved references to external identifiers and their value size |
229 | | std::map<yul::Identifier const*, ExternalIdentifierInfo> externalReferences; |
230 | | /// Information generated during analysis phase. |
231 | | std::shared_ptr<yul::AsmAnalysisInfo> analysisInfo; |
232 | | /// True, if the assembly block was annotated to be memory-safe. |
233 | | bool markedMemorySafe = false; |
234 | | /// True, if the assembly block involves any memory opcode or assigns to variables in memory. |
235 | | util::SetOnce<bool> hasMemoryEffects; |
236 | | }; |
237 | | |
238 | | struct BlockAnnotation: StatementAnnotation, ScopableAnnotation |
239 | | { |
240 | | }; |
241 | | |
242 | | struct TryCatchClauseAnnotation: ASTAnnotation, ScopableAnnotation |
243 | | { |
244 | | }; |
245 | | |
246 | | struct ForStatementAnnotation: StatementAnnotation, ScopableAnnotation |
247 | | { |
248 | | util::SetOnce<bool> isSimpleCounterLoop; |
249 | | }; |
250 | | |
251 | | struct ReturnAnnotation: StatementAnnotation |
252 | | { |
253 | | /// Reference to the return parameters of the function. |
254 | | ParameterList const* functionReturnParameters = nullptr; |
255 | | /// Reference to the function containing the return statement. |
256 | | FunctionDefinition const* function = nullptr; |
257 | | }; |
258 | | |
259 | | struct TypeNameAnnotation: ASTAnnotation |
260 | | { |
261 | | /// Type declared by this type name, i.e. type of a variable where this type name is used. |
262 | | /// Set during reference resolution stage. |
263 | | Type const* type = nullptr; |
264 | | }; |
265 | | |
266 | | struct IdentifierPathAnnotation: ASTAnnotation |
267 | | { |
268 | | /// Referenced declaration, set during reference resolution stage. |
269 | | Declaration const* referencedDeclaration = nullptr; |
270 | | /// What kind of lookup needs to be done (static, virtual, super) find the declaration. |
271 | | util::SetOnce<VirtualLookup> requiredLookup; |
272 | | |
273 | | /// Declaration of each path element. |
274 | | std::vector<Declaration const*> pathDeclarations; |
275 | | }; |
276 | | |
277 | | struct ExpressionAnnotation: ASTAnnotation |
278 | | { |
279 | | /// Inferred type of the expression. |
280 | | Type const* type = nullptr; |
281 | | /// Whether the expression is a constant variable |
282 | | util::SetOnce<bool> isConstant; |
283 | | /// Whether the expression is pure, i.e. compile-time constant. |
284 | | util::SetOnce<bool> isPure; |
285 | | /// Whether it is an LValue (i.e. something that can be assigned to). |
286 | | util::SetOnce<bool> isLValue; |
287 | | /// Whether the expression is used in a context where the LValue is actually required. |
288 | | bool willBeWrittenTo = false; |
289 | | |
290 | | /// Types and - if given - names of arguments if the expr. is a function |
291 | | /// that is called, used for overload resolution |
292 | | std::optional<FuncCallArguments> arguments; |
293 | | |
294 | | /// True if the expression consists solely of the name of the function and the function is called immediately |
295 | | /// instead of being stored or processed. The name may be qualified with the name of a contract, library |
296 | | /// module, etc., that clarifies the scope. For example: `m.L.f()`, where `m` is a module, `L` is a library |
297 | | /// and `f` is a function is a direct call. This means that the function to be called is known at compilation |
298 | | /// time and it's not necessary to rely on any runtime dispatch mechanism to resolve it. |
299 | | /// Note that even the simplest expressions, like `(f)()`, result in an indirect call even if they consist of |
300 | | /// values known at compilation time. |
301 | | bool calledDirectly = false; |
302 | | }; |
303 | | |
304 | | struct IdentifierAnnotation: ExpressionAnnotation |
305 | | { |
306 | | /// Referenced declaration, set at latest during overload resolution stage. |
307 | | Declaration const* referencedDeclaration = nullptr; |
308 | | /// What kind of lookup needs to be done (static, virtual, super) find the declaration. |
309 | | util::SetOnce<VirtualLookup> requiredLookup; |
310 | | /// List of possible declarations it could refer to (can contain duplicates). |
311 | | std::vector<Declaration const*> candidateDeclarations; |
312 | | /// List of possible declarations it could refer to. |
313 | | std::vector<Declaration const*> overloadedDeclarations; |
314 | | }; |
315 | | |
316 | | struct MemberAccessAnnotation: ExpressionAnnotation |
317 | | { |
318 | | /// Referenced declaration, set at latest during overload resolution stage. |
319 | | Declaration const* referencedDeclaration = nullptr; |
320 | | /// What kind of lookup needs to be done (static, virtual, super) find the declaration. |
321 | | util::SetOnce<VirtualLookup> requiredLookup; |
322 | | }; |
323 | | |
324 | | struct OperationAnnotation: ExpressionAnnotation |
325 | | { |
326 | | util::SetOnce<FunctionDefinition const*> userDefinedFunction; |
327 | | }; |
328 | | |
329 | | struct BinaryOperationAnnotation: OperationAnnotation |
330 | | { |
331 | | /// The common type that is used for the operation, not necessarily the result type (which |
332 | | /// e.g. for comparisons is bool). |
333 | | Type const* commonType = nullptr; |
334 | | }; |
335 | | |
336 | | enum class FunctionCallKind |
337 | | { |
338 | | FunctionCall, |
339 | | TypeConversion, |
340 | | StructConstructorCall |
341 | | }; |
342 | | |
343 | | struct FunctionCallAnnotation: ExpressionAnnotation |
344 | | { |
345 | | util::SetOnce<FunctionCallKind> kind; |
346 | | /// If true, this is the external call of a try statement. |
347 | | bool tryCall = false; |
348 | | }; |
349 | | |
350 | | } |