Coverage Report

Created: 2026-06-30 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/solidity/libsolidity/ast/AST.cpp
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 2014
21
 * Solidity abstract syntax tree.
22
 */
23
24
#include <libsolidity/ast/AST.h>
25
26
#include <libsolidity/ast/CallGraph.h>
27
#include <libsolidity/ast/ASTVisitor.h>
28
#include <libsolidity/ast/AST_accept.h>
29
#include <libsolidity/ast/TypeProvider.h>
30
#include <libsolutil/FunctionSelector.h>
31
#include <libsolutil/Keccak256.h>
32
33
#include <range/v3/range/conversion.hpp>
34
#include <range/v3/view/tail.hpp>
35
#include <range/v3/view/zip.hpp>
36
37
#include <boost/algorithm/string.hpp>
38
39
#include <functional>
40
#include <utility>
41
42
using namespace solidity;
43
using namespace solidity::frontend;
44
45
namespace
46
{
47
TryCatchClause const* findClause(std::vector<ASTPointer<TryCatchClause>> const& _clauses, std::optional<std::string> _errorName = {})
48
318
{
49
318
  for (auto const& clause: ranges::views::tail(_clauses))
50
318
    if (_errorName.has_value() ? clause->errorName() == _errorName : clause->errorName().empty())
51
106
      return clause.get();
52
212
  return nullptr;
53
318
}
54
}
55
56
ASTNode::ASTNode(std::int64_t _id, SourceLocation _location):
57
2.18M
  m_id(_id),
58
2.18M
  m_location(std::move(_location))
59
2.18M
{
60
2.18M
}
61
62
Declaration const* ASTNode::referencedDeclaration(Expression const& _expression)
63
60.2k
{
64
60.2k
  if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_expression))
65
9.46k
    return memberAccess->annotation().referencedDeclaration;
66
50.8k
  else if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(&_expression))
67
0
    return identifierPath->annotation().referencedDeclaration;
68
50.8k
  else if (auto const* identifier = dynamic_cast<Identifier const*>(&_expression))
69
20.2k
    return identifier->annotation().referencedDeclaration;
70
30.5k
  else
71
30.5k
    return nullptr;
72
60.2k
}
73
74
FunctionDefinition const* ASTNode::resolveFunctionCall(FunctionCall const& _functionCall, ContractDefinition const* _mostDerivedContract)
75
9.62k
{
76
9.62k
  auto const* functionDef = dynamic_cast<FunctionDefinition const*>(
77
9.62k
    ASTNode::referencedDeclaration(_functionCall.expression())
78
9.62k
  );
79
80
9.62k
  if (!functionDef)
81
195
    return nullptr;
82
83
9.43k
  if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_functionCall.expression()))
84
259
  {
85
259
    if (*memberAccess->annotation().requiredLookup == VirtualLookup::Super)
86
54
    {
87
54
      if (auto const typeType = dynamic_cast<TypeType const*>(memberAccess->expression().annotation().type))
88
54
        if (auto const contractType = dynamic_cast<ContractType const*>(typeType->actualType()))
89
54
        {
90
54
          solAssert(_mostDerivedContract, "");
91
54
          solAssert(contractType->isSuper(), "");
92
54
          ContractDefinition const* superContract = contractType->contractDefinition().superContract(*_mostDerivedContract);
93
94
54
          return &functionDef->resolveVirtual(
95
54
            *_mostDerivedContract,
96
54
            superContract
97
54
          );
98
54
        }
99
54
    }
100
205
    else
101
259
      solAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Static, "");
102
259
  }
103
9.17k
  else if (auto const* identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
104
9.17k
  {
105
9.17k
    solAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, "");
106
9.17k
    if (functionDef->virtualSemantics())
107
84
    {
108
84
      solAssert(_mostDerivedContract, "");
109
84
      return &functionDef->resolveVirtual(*_mostDerivedContract);
110
84
    }
111
9.17k
  }
112
0
  else
113
9.17k
    solAssert(false, "");
114
115
9.29k
  return functionDef;
116
9.43k
}
117
118
ASTAnnotation& ASTNode::annotation() const
119
180k
{
120
180k
  if (!m_annotation)
121
94.3k
    m_annotation = std::make_unique<ASTAnnotation>();
122
180k
  return *m_annotation;
123
180k
}
124
125
SourceUnitAnnotation& SourceUnit::annotation() const
126
495k
{
127
495k
  return initAnnotation<SourceUnitAnnotation>();
128
495k
}
129
130
std::set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, std::set<SourceUnit const*> _skipList) const
131
67.9k
{
132
67.9k
  std::set<SourceUnit const*> sourceUnits;
133
67.9k
  referencedSourceUnits(sourceUnits, _recurse, _skipList);
134
67.9k
  return sourceUnits;
135
67.9k
}
136
137
void SourceUnit::referencedSourceUnits(std::set<SourceUnit const*>& _referencedSourceUnits, bool _recurse, std::set<SourceUnit const*>& _skipList) const
138
71.0k
{
139
71.0k
  for (ImportDirective const* importDirective: filteredNodes<ImportDirective>(nodes()))
140
5.30k
  {
141
5.30k
    auto const& sourceUnit = importDirective->annotation().sourceUnit;
142
5.30k
    auto [skipListIt, notOnSkipListYet] = _skipList.insert(sourceUnit);
143
5.30k
    if (notOnSkipListYet)
144
3.07k
    {
145
3.07k
      _referencedSourceUnits.insert(sourceUnit);
146
3.07k
      if (_recurse)
147
3.07k
        sourceUnit->referencedSourceUnits(_referencedSourceUnits, true, _skipList);
148
3.07k
    }
149
5.30k
  }
150
71.0k
}
151
152
ImportAnnotation& ImportDirective::annotation() const
153
23.5k
{
154
23.5k
  return initAnnotation<ImportAnnotation>();
155
23.5k
}
156
157
Type const* ImportDirective::type() const
158
160
{
159
160
  solAssert(!!annotation().sourceUnit, "");
160
160
  return TypeProvider::module(*annotation().sourceUnit);
161
160
}
162
163
bool ContractDefinition::derivesFrom(ContractDefinition const& _base) const
164
16.2k
{
165
16.2k
  return util::contains(annotation().linearizedBaseContracts, &_base);
166
16.2k
}
167
168
std::map<util::FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const
169
69.4k
{
170
69.4k
  auto exportedFunctionList = interfaceFunctionList(_includeInheritedFunctions);
171
172
69.4k
  std::map<util::FixedHash<4>, FunctionTypePointer> exportedFunctions;
173
69.4k
  for (auto const& it: exportedFunctionList)
174
80.3k
    exportedFunctions.insert(it);
175
176
69.4k
  solAssert(
177
69.4k
    exportedFunctionList.size() == exportedFunctions.size(),
178
69.4k
    "Hash collision at Function Definition Hash calculation"
179
69.4k
  );
180
181
69.4k
  return exportedFunctions;
182
69.4k
}
183
184
FunctionDefinition const* ContractDefinition::constructor() const
185
539k
{
186
539k
  for (FunctionDefinition const* f: definedFunctions())
187
506k
    if (f->isConstructor())
188
76.9k
      return f;
189
462k
  return nullptr;
190
539k
}
191
192
bool ContractDefinition::canBeDeployed() const
193
102k
{
194
102k
  return !abstract() && !isInterface();
195
102k
}
196
197
FunctionDefinition const* ContractDefinition::fallbackFunction() const
198
85.9k
{
199
85.9k
  for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
200
97.2k
    for (FunctionDefinition const* f: contract->definedFunctions())
201
131k
      if (f->isFallback())
202
1.21k
        return f;
203
84.7k
  return nullptr;
204
85.9k
}
205
206
FunctionDefinition const* ContractDefinition::receiveFunction() const
207
64.2k
{
208
64.2k
  for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
209
70.8k
    for (FunctionDefinition const* f: contract->definedFunctions())
210
106k
      if (f->isReceive())
211
537
        return f;
212
63.7k
  return nullptr;
213
64.2k
}
214
215
std::vector<EventDefinition const*> const& ContractDefinition::definedInterfaceEvents() const
216
29.0k
{
217
29.0k
  return m_interfaceEvents.init([&]{
218
14.2k
    std::set<std::string> eventsSeen;
219
14.2k
    std::vector<EventDefinition const*> interfaceEvents;
220
221
14.2k
    for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
222
15.8k
      for (EventDefinition const* e: contract->events())
223
1.50k
      {
224
        /// NOTE: this requires the "internal" version of an Event,
225
        ///       though here internal strictly refers to visibility,
226
        ///       and not to function encoding (jump vs. call)
227
1.50k
        FunctionType const* functionType = e->functionType(true);
228
1.50k
        solAssert(functionType, "");
229
1.50k
        std::string eventSignature = functionType->externalSignature();
230
1.50k
        if (eventsSeen.count(eventSignature) == 0)
231
1.50k
        {
232
1.50k
          eventsSeen.insert(eventSignature);
233
1.50k
          interfaceEvents.push_back(e);
234
1.50k
        }
235
1.50k
      }
236
14.2k
    return interfaceEvents;
237
14.2k
  });
238
29.0k
}
239
240
std::vector<EventDefinition const*> const ContractDefinition::usedInterfaceEvents() const
241
43.2k
{
242
43.2k
  solAssert(annotation().creationCallGraph.set(), "");
243
244
43.2k
  return util::convertContainer<std::vector<EventDefinition const*>>(
245
43.2k
    (*annotation().creationCallGraph)->emittedEvents +
246
43.2k
    (*annotation().deployedCallGraph)->emittedEvents
247
43.2k
  );
248
43.2k
}
249
250
std::vector<EventDefinition const*> ContractDefinition::interfaceEvents(bool _requireCallGraph) const
251
14.2k
{
252
14.2k
  std::set<EventDefinition const*, CompareByID> result;
253
14.2k
  for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
254
15.8k
    result += contract->events();
255
14.2k
  solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set());
256
14.2k
  if (_requireCallGraph)
257
14.2k
    solAssert(annotation().creationCallGraph.set());
258
14.2k
  if (annotation().creationCallGraph.set())
259
14.2k
    result += usedInterfaceEvents();
260
  // We could filter out all events that do not have an external interface
261
  // if _requireCallGraph is false.
262
14.2k
  return util::convertContainer<std::vector<EventDefinition const*>>(std::move(result));
263
14.2k
}
264
265
std::vector<ErrorDefinition const*> ContractDefinition::interfaceErrors(bool _requireCallGraph) const
266
58.0k
{
267
58.0k
  std::set<ErrorDefinition const*, CompareByID> result;
268
58.0k
  for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
269
64.7k
    result += filteredNodes<ErrorDefinition>(contract->m_subNodes);
270
58.0k
  solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set(), "");
271
58.0k
  if (_requireCallGraph)
272
58.0k
    solAssert(annotation().creationCallGraph.set(), "");
273
58.0k
  if (annotation().creationCallGraph.set())
274
58.0k
    result +=
275
58.0k
      (*annotation().creationCallGraph)->usedErrors +
276
58.0k
      (*annotation().deployedCallGraph)->usedErrors;
277
58.0k
  return util::convertContainer<std::vector<ErrorDefinition const*>>(std::move(result));
278
58.0k
}
279
280
std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const
281
106k
{
282
106k
  return m_interfaceFunctionList[_includeInheritedFunctions].init([&]{
283
21.6k
    std::set<std::string> signaturesSeen;
284
21.6k
    std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> interfaceFunctionList;
285
286
21.6k
    for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
287
26.5k
    {
288
26.5k
      if (_includeInheritedFunctions == false && contract != this)
289
0
        continue;
290
26.5k
      std::vector<FunctionTypePointer> functions;
291
26.5k
      for (FunctionDefinition const* f: contract->definedFunctions())
292
25.0k
        if (f->isPartOfExternalInterface())
293
19.3k
          functions.push_back(TypeProvider::function(*f, FunctionType::Kind::External));
294
26.5k
      for (VariableDeclaration const* v: contract->stateVariables())
295
11.2k
        if (v->isPartOfExternalInterface())
296
4.22k
          functions.push_back(TypeProvider::function(*v));
297
26.5k
      for (FunctionTypePointer const& fun: functions)
298
23.5k
      {
299
23.5k
        if (!fun->interfaceFunctionType())
300
          // Fails hopefully because we already registered the error
301
37
          continue;
302
23.5k
        std::string functionSignature = fun->externalSignature();
303
23.5k
        if (signaturesSeen.count(functionSignature) == 0)
304
21.1k
        {
305
21.1k
          signaturesSeen.insert(functionSignature);
306
21.1k
          interfaceFunctionList.emplace_back(util::selectorFromSignatureH32(functionSignature), fun);
307
21.1k
        }
308
23.5k
      }
309
26.5k
    }
310
311
21.6k
    return interfaceFunctionList;
312
21.6k
  });
313
106k
}
314
315
uint32_t ContractDefinition::interfaceId() const
316
18
{
317
18
  uint32_t result{0};
318
18
  for (auto const& function: interfaceFunctionList(false))
319
33
    result ^= fromBigEndian<uint32_t>(function.first.ref());
320
18
  return result;
321
18
}
322
323
Type const* ContractDefinition::type() const
324
1.17k
{
325
1.17k
  return TypeProvider::typeType(TypeProvider::contract(*this));
326
1.17k
}
327
328
ContractDefinitionAnnotation& ContractDefinition::annotation() const
329
3.95M
{
330
3.95M
  return initAnnotation<ContractDefinitionAnnotation>();
331
3.95M
}
332
333
ContractDefinition const* ContractDefinition::superContract(ContractDefinition const& _mostDerivedContract) const
334
11.4k
{
335
11.4k
  auto const& hierarchy = _mostDerivedContract.annotation().linearizedBaseContracts;
336
11.4k
  auto it = find(hierarchy.begin(), hierarchy.end(), this);
337
11.4k
  solAssert(it != hierarchy.end(), "Base not found in inheritance hierarchy.");
338
11.4k
  ++it;
339
11.4k
  if (it == hierarchy.end())
340
9.79k
    return nullptr;
341
1.68k
  else
342
1.68k
  {
343
1.68k
    solAssert(*it != this, "");
344
1.68k
    return *it;
345
1.68k
  }
346
11.4k
}
347
348
FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition const& _mostDerivedContract) const
349
10.8k
{
350
10.8k
  ContractDefinition const* next = superContract(_mostDerivedContract);
351
10.8k
  if (next == nullptr)
352
9.79k
    return nullptr;
353
1.04k
  for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
354
2.72k
    if (c == next || next == nullptr)
355
1.46k
    {
356
1.46k
      if (c->constructor())
357
382
        return c->constructor();
358
1.08k
      next = nullptr;
359
1.08k
    }
360
361
664
  return nullptr;
362
1.04k
}
363
364
std::multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const
365
1.54k
{
366
1.54k
  return m_definedFunctionsByName.init([&]{
367
129
    std::multimap<std::string, FunctionDefinition const*> result;
368
129
    for (FunctionDefinition const* fun: filteredNodes<FunctionDefinition>(m_subNodes))
369
188
      result.insert({fun->name(), fun});
370
129
    return result;
371
129
  });
372
1.54k
}
373
374
StorageLayoutSpecifier::StorageLayoutSpecifier(
375
  int64_t _id,
376
  SourceLocation const& _location,
377
  ASTPointer<Expression> _baseSlotExpression
378
):
379
35
  ASTNode(_id, _location),
380
35
  m_baseSlotExpression(_baseSlotExpression)
381
35
{
382
35
  solAssert(m_baseSlotExpression);
383
35
  solAssert(_location.contains(m_baseSlotExpression->location()));
384
35
}
385
386
StorageLayoutSpecifierAnnotation& StorageLayoutSpecifier::annotation() const
387
0
{
388
0
  return initAnnotation<StorageLayoutSpecifierAnnotation>();
389
0
}
390
391
TypeNameAnnotation& TypeName::annotation() const
392
822k
{
393
822k
  return initAnnotation<TypeNameAnnotation>();
394
822k
}
395
396
Type const* UserDefinedValueTypeDefinition::type() const
397
412
{
398
412
  solAssert(m_underlyingType->annotation().type, "");
399
412
  return TypeProvider::typeType(TypeProvider::userDefinedValueType(*this));
400
412
}
401
402
TypeDeclarationAnnotation& UserDefinedValueTypeDefinition::annotation() const
403
16.9k
{
404
16.9k
  return initAnnotation<TypeDeclarationAnnotation>();
405
16.9k
}
406
407
std::vector<std::pair<ASTPointer<IdentifierPath>, std::optional<Token>>> UsingForDirective::functionsAndOperators() const
408
1.78k
{
409
1.78k
  return ranges::zip_view(m_functionsOrLibrary, m_operators) | ranges::to<std::vector>;
410
1.78k
}
411
412
Type const* StructDefinition::type() const
413
265
{
414
265
  solAssert(annotation().recursive.has_value(), "Requested struct type before DeclarationTypeChecker.");
415
265
  return TypeProvider::typeType(TypeProvider::structType(*this, DataLocation::Storage));
416
265
}
417
418
StructDeclarationAnnotation& StructDefinition::annotation() const
419
11.0M
{
420
11.0M
  return initAnnotation<StructDeclarationAnnotation>();
421
11.0M
}
422
423
Type const* EnumValue::type() const
424
0
{
425
0
  auto parentDef = dynamic_cast<EnumDefinition const*>(scope());
426
0
  solAssert(parentDef, "Enclosing Scope of EnumValue was not set");
427
0
  return TypeProvider::enumType(*parentDef);
428
0
}
429
430
Type const* EnumDefinition::type() const
431
176
{
432
176
  return TypeProvider::typeType(TypeProvider::enumType(*this));
433
176
}
434
435
TypeDeclarationAnnotation& EnumDefinition::annotation() const
436
8.77k
{
437
8.77k
  return initAnnotation<TypeDeclarationAnnotation>();
438
8.77k
}
439
440
bool FunctionDefinition::libraryFunction() const
441
54.3k
{
442
54.3k
  if (auto const* contractDef = dynamic_cast<ContractDefinition const*>(scope()))
443
52.8k
    return contractDef->isLibrary();
444
1.49k
  return false;
445
54.3k
}
446
447
Visibility FunctionDefinition::defaultVisibility() const
448
13.2k
{
449
13.2k
  solAssert(!isConstructor(), "");
450
13.2k
  return isFree() ? Visibility::Internal : Declaration::defaultVisibility();
451
13.2k
}
452
453
FunctionTypePointer FunctionDefinition::functionType(bool _internal) const
454
15.7k
{
455
15.7k
  if (_internal)
456
1.37k
  {
457
1.37k
    switch (visibility())
458
1.37k
    {
459
0
    case Visibility::Default:
460
0
      solAssert(false, "visibility() should not return Default");
461
8
    case Visibility::Private:
462
1.21k
    case Visibility::Internal:
463
1.37k
    case Visibility::Public:
464
1.37k
      return TypeProvider::function(*this, FunctionType::Kind::Internal);
465
0
    case Visibility::External:
466
0
      return {};
467
1.37k
    }
468
1.37k
  }
469
14.3k
  else
470
14.3k
  {
471
14.3k
    switch (visibility())
472
14.3k
    {
473
0
    case Visibility::Default:
474
0
      solAssert(false, "visibility() should not return Default");
475
7
    case Visibility::Private:
476
719
    case Visibility::Internal:
477
719
      return {};
478
10.6k
    case Visibility::Public:
479
13.6k
    case Visibility::External:
480
13.6k
      return TypeProvider::function(*this, FunctionType::Kind::External);
481
14.3k
    }
482
14.3k
  }
483
484
  // To make the compiler happy
485
0
  return {};
486
15.7k
}
487
488
Type const* FunctionDefinition::type() const
489
11.6k
{
490
11.6k
  solAssert(visibility() != Visibility::External, "");
491
11.6k
  return TypeProvider::function(*this, FunctionType::Kind::Internal);
492
11.6k
}
493
494
Type const* FunctionDefinition::typeViaContractName(ContractNameAccessKind const _accessKind) const
495
1.28k
{
496
  // TODO: Fails because private library functions are attachable but not visible (issue #16721)
497
  //solAssert(isVisibleViaContractName(_accessKind));
498
1.28k
  switch (_accessKind)
499
1.28k
  {
500
235
    case ContractNameAccessKind::Local:
501
235
    {
502
235
      solAssert(!libraryFunction(), "Library members can only be accessed via library name.");
503
235
      solAssert(visibility() > Visibility::Private, "Private non-library member is not visible via contract type name");
504
505
235
      if (!Declaration::isVisibleInContract() || !isImplemented())
506
        // If is external or has no implementation, it cannot be called using contract type name. In case of accessing
507
        // via contract type name, only declaration is available, to be used in non calling context. I.e. to access
508
        // function selector `C.foo.selector` where foo has external visibility.
509
72
        return TypeProvider::function(*this, FunctionType::Kind::Declaration);
510
163
      else
511
        // If call is in local (or deriving) scope, function is visible in contract (non-external) and it has an
512
        // implementation, internal call is used.
513
163
        return type();
514
235
    }
515
132
    case ContractNameAccessKind::Foreign:
516
132
    {
517
132
      solAssert(!libraryFunction(), "Library members can only be accessed via library name.");
518
132
      solAssert(isVisibleViaContractTypeAccess(), "Invisible member accessed via contract name.");
519
      // Foreign contract member function being accessed via contract type name, cannot be called.
520
132
      return TypeProvider::function(*this, FunctionType::Kind::Declaration);
521
235
    }
522
918
    case ContractNameAccessKind::Library:
523
918
    {
524
      // We could theoretically distinguish local and foreign scope for libraries but it does not affect the type,
525
      // so we don't. Access to private members from foreign scopes is not allowed by the type checker, so if we
526
      // get such a function here, we assume the scope is local. Note that access to private library members via
527
      // library name is not allowed, but you can (sometimes, see issue [#16721](#16721)) attach them via `using`
528
      // statement.
529
918
      solAssert(libraryFunction(), "Non-library members cannot be accessed via library name.");
530
      // In case of library contract, member call kind depends on its visibility.
531
918
      if (isPublic())
532
        // When Lib.foo is public or external, an external call (delegate call) is used.
533
370
        return FunctionType(*this).asExternallyCallableFunction(true /* _inLibrary */);
534
548
      else
535
        // For private or internal visibility, internal call is used.
536
        // Private library members can be accessed in context of `using` statement.
537
548
        return type();
538
918
    }
539
1.28k
  }
540
0
  util::unreachable();
541
0
}
542
543
Type const* FunctionDefinition::typeWhenAttached() const
544
1.69k
{
545
1.69k
  solAssert(isFree() || libraryFunction());
546
1.69k
  return libraryFunction() ? typeViaContractName(ContractNameAccessKind::Library) : type();
547
1.69k
}
548
549
std::string FunctionDefinition::externalSignature() const
550
0
{
551
0
  return TypeProvider::function(*this)->externalSignature();
552
0
}
553
554
std::string FunctionDefinition::externalIdentifierHex() const
555
0
{
556
0
  return TypeProvider::function(*this)->externalIdentifierHex();
557
0
}
558
559
FunctionDefinitionAnnotation& FunctionDefinition::annotation() const
560
929k
{
561
929k
  return initAnnotation<FunctionDefinitionAnnotation>();
562
929k
}
563
564
FunctionDefinition const& FunctionDefinition::resolveVirtual(
565
  ContractDefinition const& _mostDerivedContract,
566
  ContractDefinition const* _searchStart
567
) const
568
25.7k
{
569
25.7k
  solAssert(!isConstructor(), "");
570
25.7k
  solAssert(!name().empty(), "");
571
572
  // If we are not doing super-lookup and the function is not virtual, we can stop here.
573
25.7k
  if (_searchStart == nullptr && !virtualSemantics())
574
24.3k
    return *this;
575
576
1.37k
  solAssert(!isFree(), "");
577
1.37k
  solAssert(isOrdinary(), "");
578
1.37k
  solAssert(!libraryFunction(), "");
579
580
  // We actually do not want the externally callable function here.
581
  // This is just to add an assertion since the comparison used to be less strict.
582
1.37k
  FunctionType const* externalFunctionType = TypeProvider::function(*this)->asExternallyCallableFunction(false);
583
584
1.37k
  bool foundSearchStart = (_searchStart == nullptr);
585
1.37k
  for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
586
2.52k
  {
587
2.52k
    if (!foundSearchStart && c != _searchStart)
588
983
      continue;
589
1.54k
    else
590
1.54k
      foundSearchStart = true;
591
592
1.54k
    for (FunctionDefinition const* function: c->definedFunctions(name()))
593
1.40k
      if (
594
        // With super lookup analysis guarantees that there is an implemented function in the chain.
595
        // With virtual lookup there are valid cases where returning an unimplemented one is fine.
596
1.40k
        (function->isImplemented() || _searchStart == nullptr) &&
597
1.39k
        FunctionType(*function).asExternallyCallableFunction(false)->hasEqualParameterTypes(*externalFunctionType)
598
1.40k
      )
599
1.37k
      {
600
1.37k
        solAssert(FunctionType(*function).hasEqualParameterTypes(*TypeProvider::function(*this)));
601
1.37k
        return *function;
602
1.37k
      }
603
1.54k
  }
604
605
0
  solAssert(false, "Virtual function " + name() + " not found.");
606
0
  return *this; // not reached
607
1.37k
}
608
609
Type const* ModifierDefinition::type() const
610
5
{
611
5
  return TypeProvider::modifier(*this);
612
5
}
613
614
ModifierDefinitionAnnotation& ModifierDefinition::annotation() const
615
82.2k
{
616
82.2k
  return initAnnotation<ModifierDefinitionAnnotation>();
617
82.2k
}
618
619
ModifierDefinition const& ModifierDefinition::resolveVirtual(
620
  ContractDefinition const& _mostDerivedContract,
621
  ContractDefinition const* _searchStart
622
) const
623
36.2k
{
624
  // Super is not possible with modifiers
625
36.2k
  solAssert(_searchStart == nullptr, "Used super in connection with modifiers.");
626
627
  // The modifier is not virtual, we can stop here.
628
36.2k
  if (!virtualSemantics())
629
35.0k
    return *this;
630
631
1.20k
  solAssert(!dynamic_cast<ContractDefinition const&>(*scope()).isLibrary(), "");
632
633
1.20k
  for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
634
1.25k
    for (ModifierDefinition const* modifier: c->functionModifiers())
635
1.23k
      if (modifier->name() == name())
636
1.20k
        return *modifier;
637
638
0
  solAssert(false, "Virtual modifier " + name() + " not found.");
639
0
  return *this; // not reached
640
1.20k
}
641
642
643
Type const* EventDefinition::type() const
644
1.38k
{
645
1.38k
  return TypeProvider::function(*this);
646
1.38k
}
647
648
FunctionTypePointer EventDefinition::functionType(bool _internal) const
649
16.8k
{
650
16.8k
  if (_internal)
651
16.0k
    return TypeProvider::function(*this);
652
816
  else
653
816
    return nullptr;
654
16.8k
}
655
656
EventDefinitionAnnotation& EventDefinition::annotation() const
657
70.1k
{
658
70.1k
  return initAnnotation<EventDefinitionAnnotation>();
659
70.1k
}
660
661
Type const* ErrorDefinition::type() const
662
100
{
663
100
  return TypeProvider::function(*this);
664
100
}
665
666
FunctionTypePointer ErrorDefinition::functionType(bool _internal) const
667
632
{
668
632
  if (_internal)
669
632
    return TypeProvider::function(*this);
670
0
  else
671
0
    return nullptr;
672
632
}
673
674
ErrorDefinitionAnnotation& ErrorDefinition::annotation() const
675
12.3k
{
676
12.3k
  return initAnnotation<ErrorDefinitionAnnotation>();
677
12.3k
}
678
679
SourceUnit const& Scopable::sourceUnit() const
680
255k
{
681
255k
  ASTNode const* s = scope();
682
255k
  solAssert(s, "");
683
  // will not always be a declaration
684
283k
  while (dynamic_cast<Scopable const*>(s) && dynamic_cast<Scopable const*>(s)->scope())
685
28.3k
    s = dynamic_cast<Scopable const*>(s)->scope();
686
255k
  return dynamic_cast<SourceUnit const&>(*s);
687
255k
}
688
689
CallableDeclaration const* Scopable::functionOrModifierDefinition() const
690
0
{
691
0
  ASTNode const* s = scope();
692
0
  solAssert(s, "");
693
0
  while (dynamic_cast<Scopable const*>(s))
694
0
  {
695
0
    if (auto funDef = dynamic_cast<FunctionDefinition const*>(s))
696
0
      return funDef;
697
0
    if (auto modDef = dynamic_cast<ModifierDefinition const*>(s))
698
0
      return modDef;
699
0
    s = dynamic_cast<Scopable const*>(s)->scope();
700
0
  }
701
0
  return nullptr;
702
0
}
703
704
std::string Scopable::sourceUnitName() const
705
75.5k
{
706
75.5k
  return *sourceUnit().annotation().path;
707
75.5k
}
708
709
bool Declaration::isEnumValue() const
710
149k
{
711
149k
  solAssert(scope(), "");
712
149k
  return dynamic_cast<EnumDefinition const*>(scope());
713
149k
}
714
715
bool Declaration::isStructMember() const
716
169k
{
717
169k
  solAssert(scope(), "");
718
169k
  return dynamic_cast<StructDefinition const*>(scope());
719
169k
}
720
721
bool Declaration::isEventOrErrorParameter() const
722
249k
{
723
249k
  solAssert(scope(), "");
724
249k
  return dynamic_cast<EventDefinition const*>(scope()) || dynamic_cast<ErrorDefinition const*>(scope());
725
249k
}
726
727
bool Declaration::isVisibleAsUnqualifiedName() const
728
169k
{
729
169k
  if (!scope())
730
199
    return true;
731
169k
  if (isStructMember() || isEnumValue() || isEventOrErrorParameter())
732
22.5k
    return false;
733
146k
  if (auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(scope()))
734
15.7k
    if (!functionDefinition->isImplemented())
735
99
      return false; // parameter of a function without body
736
146k
  return true;
737
146k
}
738
739
DeclarationAnnotation& Declaration::annotation() const
740
66.8k
{
741
66.8k
  return initAnnotation<DeclarationAnnotation>();
742
66.8k
}
743
744
bool VariableDeclaration::isLValue() const
745
114k
{
746
  // Constant declared variables are Read-Only
747
114k
  return !isConstant();
748
114k
}
749
750
bool VariableDeclaration::isLocalVariable() const
751
214k
{
752
214k
  auto s = scope();
753
214k
  return
754
214k
    dynamic_cast<FunctionTypeName const*>(s) ||
755
213k
    dynamic_cast<CallableDeclaration const*>(s) ||
756
102k
    dynamic_cast<Block const*>(s) ||
757
56.5k
    dynamic_cast<TryCatchClause const*>(s) ||
758
56.2k
    dynamic_cast<ForStatement const*>(s);
759
214k
}
760
761
bool VariableDeclaration::isCallableOrCatchParameter() const
762
153k
{
763
153k
  if (isReturnParameter() || isTryCatchParameter())
764
32.9k
    return true;
765
766
121k
  std::vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
767
768
121k
  if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
769
643
    parameters = &funTypeName->parameterTypes();
770
120k
  else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
771
63.7k
    parameters = &callable->parameters();
772
773
121k
  if (parameters)
774
64.3k
    for (auto const& variable: *parameters)
775
90.8k
      if (variable.get() == this)
776
64.3k
        return true;
777
56.6k
  return false;
778
121k
}
779
780
bool VariableDeclaration::isLocalOrReturn() const
781
60
{
782
60
  return isReturnParameter() || (isLocalVariable() && !isCallableOrCatchParameter());
783
60
}
784
785
bool VariableDeclaration::isReturnParameter() const
786
182k
{
787
182k
  std::vector<ASTPointer<VariableDeclaration>> const* returnParameters = nullptr;
788
789
182k
  if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
790
868
    returnParameters = &funTypeName->returnParameterTypes();
791
182k
  else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
792
124k
    if (callable->returnParameterList())
793
116k
      returnParameters = &callable->returnParameterList()->parameters();
794
795
182k
  if (returnParameters)
796
117k
    for (auto const& variable: *returnParameters)
797
147k
      if (variable.get() == this)
798
45.7k
        return true;
799
137k
  return false;
800
182k
}
801
802
bool VariableDeclaration::isTryCatchParameter() const
803
130k
{
804
130k
  return dynamic_cast<TryCatchClause const*>(scope());
805
130k
}
806
807
bool VariableDeclaration::isExternalCallableParameter() const
808
50
{
809
50
  if (!isCallableOrCatchParameter())
810
0
    return false;
811
812
50
  if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
813
43
    if (callable->visibility() == Visibility::External)
814
26
      return !isReturnParameter();
815
816
24
  return false;
817
50
}
818
819
bool VariableDeclaration::isPublicCallableParameter() const
820
16.4k
{
821
16.4k
  if (!isCallableOrCatchParameter())
822
7.74k
    return false;
823
824
8.73k
  if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
825
8.55k
    if (callable->visibility() == Visibility::Public)
826
3.94k
      return !isReturnParameter();
827
828
4.78k
  return false;
829
8.73k
}
830
831
bool VariableDeclaration::isInternalCallableParameter() const
832
7.57k
{
833
7.57k
  if (!isCallableOrCatchParameter())
834
0
    return false;
835
836
7.57k
  if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
837
112
    return funTypeName->visibility() == Visibility::Internal;
838
7.46k
  else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
839
7.35k
    return callable->visibility() <= Visibility::Internal;
840
104
  return false;
841
7.57k
}
842
843
bool VariableDeclaration::isConstructorParameter() const
844
48.2k
{
845
48.2k
  if (!isCallableOrCatchParameter())
846
15.5k
    return false;
847
32.7k
  if (auto const* function = dynamic_cast<FunctionDefinition const*>(scope()))
848
29.1k
    return function->isConstructor();
849
3.66k
  return false;
850
32.7k
}
851
852
bool VariableDeclaration::isLibraryFunctionParameter() const
853
22.1k
{
854
22.1k
  if (!isCallableOrCatchParameter())
855
7.74k
    return false;
856
14.4k
  if (auto const* funDef = dynamic_cast<FunctionDefinition const*>(scope()))
857
12.5k
    return funDef->libraryFunction();
858
1.82k
  return false;
859
14.4k
}
860
861
bool VariableDeclaration::hasReferenceOrMappingType() const
862
118k
{
863
118k
  solAssert(typeName().annotation().type, "Can only be called after reference resolution");
864
118k
  Type const* type = typeName().annotation().type;
865
118k
  return type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type);
866
118k
}
867
868
bool VariableDeclaration::isStateVariable() const
869
939k
{
870
939k
  return dynamic_cast<ContractDefinition const*>(scope());
871
939k
}
872
873
bool VariableDeclaration::isFileLevelVariable() const
874
284k
{
875
284k
  return dynamic_cast<SourceUnit const*>(scope());
876
284k
}
877
878
std::set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const
879
75.8k
{
880
75.8k
  using Location = VariableDeclaration::Location;
881
882
75.8k
  if (isStateVariable())
883
10.1k
    return std::set<Location>{Location::Unspecified, Location::Transient};
884
65.7k
  else if (!hasReferenceOrMappingType() || isEventOrErrorParameter())
885
42.0k
    return std::set<Location>{ Location::Unspecified };
886
23.6k
  else if (isCallableOrCatchParameter())
887
7.63k
  {
888
7.63k
    std::set<Location> locations{ Location::Memory };
889
7.63k
    if (
890
7.63k
      isConstructorParameter() ||
891
7.57k
      isInternalCallableParameter() ||
892
5.63k
      isLibraryFunctionParameter()
893
7.63k
    )
894
2.21k
      locations.insert(Location::Storage);
895
7.63k
    if (!isTryCatchParameter() && !isConstructorParameter())
896
7.46k
      locations.insert(Location::CallData);
897
898
7.63k
    return locations;
899
7.63k
  }
900
16.0k
  else if (isLocalVariable())
901
    // Further restrictions will be imposed later on.
902
3.59k
    return std::set<Location>{ Location::Memory, Location::Storage, Location::CallData };
903
12.4k
  else
904
    // Struct members etc.
905
12.4k
    return std::set<Location>{ Location::Unspecified };
906
75.8k
}
907
908
std::string VariableDeclaration::externalIdentifierHex() const
909
0
{
910
0
  solAssert(isStateVariable() && isPublic(), "Can only be called for public state variables");
911
0
  return TypeProvider::function(*this)->externalIdentifierHex();
912
0
}
913
914
Type const* VariableDeclaration::type() const
915
687k
{
916
687k
  return annotation().type;
917
687k
}
918
919
FunctionTypePointer VariableDeclaration::functionType(bool _internal) const
920
7.35k
{
921
7.35k
  if (_internal)
922
0
    return nullptr;
923
7.35k
  switch (visibility())
924
7.35k
  {
925
0
  case Visibility::Default:
926
0
    solAssert(false, "visibility() should not return Default");
927
15
  case Visibility::Private:
928
5.03k
  case Visibility::Internal:
929
5.03k
    return nullptr;
930
2.31k
  case Visibility::Public:
931
2.31k
  case Visibility::External:
932
2.31k
    return TypeProvider::function(*this);
933
7.35k
  }
934
935
  // To make the compiler happy
936
0
  return nullptr;
937
7.35k
}
938
939
VariableDeclarationAnnotation& VariableDeclaration::annotation() const
940
13.1M
{
941
13.1M
  return initAnnotation<VariableDeclarationAnnotation>();
942
13.1M
}
943
944
StatementAnnotation& Statement::annotation() const
945
195k
{
946
195k
  return initAnnotation<StatementAnnotation>();
947
195k
}
948
949
InlineAssemblyAnnotation& InlineAssembly::annotation() const
950
33.8k
{
951
33.8k
  return initAnnotation<InlineAssemblyAnnotation>();
952
33.8k
}
953
954
BlockAnnotation& Block::annotation() const
955
166k
{
956
166k
  return initAnnotation<BlockAnnotation>();
957
166k
}
958
959
TryCatchClauseAnnotation& TryCatchClause::annotation() const
960
3.72k
{
961
3.72k
  return initAnnotation<TryCatchClauseAnnotation>();
962
3.72k
}
963
964
ForStatementAnnotation& ForStatement::annotation() const
965
24.4k
{
966
24.4k
  return initAnnotation<ForStatementAnnotation>();
967
24.4k
}
968
969
ReturnAnnotation& Return::annotation() const
970
357k
{
971
357k
  return initAnnotation<ReturnAnnotation>();
972
357k
}
973
974
ExpressionAnnotation& Expression::annotation() const
975
7.28M
{
976
7.28M
  return initAnnotation<ExpressionAnnotation>();
977
7.28M
}
978
979
MemberAccessAnnotation& MemberAccess::annotation() const
980
5.16M
{
981
5.16M
  return initAnnotation<MemberAccessAnnotation>();
982
5.16M
}
983
984
OperationAnnotation& UnaryOperation::annotation() const
985
468k
{
986
468k
  return initAnnotation<OperationAnnotation>();
987
468k
}
988
989
FunctionType const* UnaryOperation::userDefinedFunctionType() const
990
17.3k
{
991
17.3k
  if (*annotation().userDefinedFunction == nullptr)
992
17.2k
    return nullptr;
993
994
88
  FunctionDefinition const* userDefinedFunction = *annotation().userDefinedFunction;
995
88
  return dynamic_cast<FunctionType const*>(userDefinedFunction->typeWhenAttached());
996
17.3k
}
997
998
FunctionType const* BinaryOperation::userDefinedFunctionType() const
999
68.2k
{
1000
68.2k
  if (*annotation().userDefinedFunction == nullptr)
1001
68.0k
    return nullptr;
1002
1003
128
  FunctionDefinition const* userDefinedFunction = *annotation().userDefinedFunction;
1004
128
  return dynamic_cast<FunctionType const*>(userDefinedFunction->typeWhenAttached());
1005
68.2k
}
1006
1007
BinaryOperationAnnotation& BinaryOperation::annotation() const
1008
1.43M
{
1009
1.43M
  return initAnnotation<BinaryOperationAnnotation>();
1010
1.43M
}
1011
1012
FunctionCallAnnotation& FunctionCall::annotation() const
1013
756k
{
1014
756k
  return initAnnotation<FunctionCallAnnotation>();
1015
756k
}
1016
1017
std::vector<ASTPointer<Expression const>> FunctionCall::sortedArguments() const
1018
30.1k
{
1019
  // normal arguments
1020
30.1k
  if (m_names.empty())
1021
29.8k
    return arguments();
1022
1023
  // named arguments
1024
324
  FunctionTypePointer functionType;
1025
324
  if (*annotation().kind == FunctionCallKind::StructConstructorCall)
1026
85
  {
1027
85
    auto const& type = dynamic_cast<TypeType const&>(*m_expression->annotation().type);
1028
85
    auto const& structType = dynamic_cast<StructType const&>(*type.actualType());
1029
85
    functionType = structType.constructorType();
1030
85
  }
1031
239
  else
1032
239
    functionType = dynamic_cast<FunctionType const*>(m_expression->annotation().type);
1033
1034
324
  std::vector<ASTPointer<Expression const>> sorted;
1035
324
  for (auto const& parameterName: functionType->parameterNames())
1036
837
  {
1037
837
    bool found = false;
1038
2.39k
    for (size_t j = 0; j < m_names.size() && !found; j++)
1039
1.55k
      if ((found = (parameterName == *m_names.at(j))))
1040
        // we found the actual parameter position
1041
837
        sorted.push_back(m_arguments.at(j));
1042
837
    solAssert(found, "");
1043
837
  }
1044
1045
324
  if (!functionType->takesArbitraryParameters())
1046
324
  {
1047
324
    solAssert(m_arguments.size() == functionType->parameterTypes().size(), "");
1048
324
    solAssert(m_arguments.size() == m_names.size(), "");
1049
324
    solAssert(m_arguments.size() == sorted.size(), "");
1050
324
  }
1051
1052
324
  return sorted;
1053
30.1k
}
1054
1055
IdentifierAnnotation& Identifier::annotation() const
1056
4.40M
{
1057
4.40M
  return initAnnotation<IdentifierAnnotation>();
1058
4.40M
}
1059
1060
ASTString Literal::valueWithoutUnderscores() const
1061
726k
{
1062
726k
  return boost::erase_all_copy(value(), "_");
1063
726k
}
1064
1065
bool Literal::isHexNumber() const
1066
1.46M
{
1067
1.46M
  if (token() != Token::Number)
1068
77.5k
    return false;
1069
1.38M
  return boost::starts_with(value(), "0x");
1070
1.46M
}
1071
1072
bool Literal::looksLikeAddress() const
1073
264k
{
1074
264k
  if (subDenomination() != SubDenomination::None)
1075
317
    return false;
1076
1077
263k
  if (!isHexNumber())
1078
257k
    return false;
1079
1080
6.54k
  return abs(int(valueWithoutUnderscores().length()) - 42) <= 1;
1081
263k
}
1082
1083
bool Literal::passesAddressChecksum() const
1084
86
{
1085
86
  solAssert(isHexNumber(), "Expected hex number");
1086
86
  return util::passesAddressChecksum(valueWithoutUnderscores(), true);
1087
86
}
1088
1089
std::string Literal::getChecksummedAddress() const
1090
24
{
1091
24
  solAssert(isHexNumber(), "Expected hex number");
1092
  /// Pad literal to be a proper hex address.
1093
24
  std::string address = valueWithoutUnderscores().substr(2);
1094
24
  if (address.length() > 40)
1095
0
    return std::string();
1096
24
  address.insert(address.begin(), 40 - address.size(), '0');
1097
24
  return util::getChecksummedAddress(address);
1098
24
}
1099
1100
TryCatchClause const* TryStatement::successClause() const
1101
648
{
1102
648
  solAssert(m_clauses.size() > 0, "");
1103
648
  return m_clauses[0].get();
1104
648
}
1105
1106
106
TryCatchClause const* TryStatement::panicClause() const {
1107
106
  return findClause(m_clauses, "Panic");
1108
106
}
1109
1110
106
TryCatchClause const* TryStatement::errorClause() const {
1111
106
  return findClause(m_clauses, "Error");
1112
106
}
1113
1114
106
TryCatchClause const* TryStatement::fallbackClause() const {
1115
106
  return findClause(m_clauses);
1116
106
}
1117
1118
/// Experimental Solidity nodes
1119
/// @{
1120
TypeClassDefinitionAnnotation& TypeClassDefinition::annotation() const
1121
264
{
1122
264
  return initAnnotation<TypeClassDefinitionAnnotation>();
1123
264
}
1124
TypeDeclarationAnnotation& TypeDefinition::annotation() const
1125
1.27k
{
1126
1.27k
  return initAnnotation<TypeDeclarationAnnotation>();
1127
1.27k
}
1128
/// @}