Coverage Report

Created: 2026-08-14 07:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}