Coverage Report

Created: 2022-08-24 06:31

/src/solidity/libsolidity/ast/AST.cpp
Line
Count
Source (jump to first uncovered line)
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/Keccak256.h>
31
32
#include <boost/algorithm/string.hpp>
33
34
#include <functional>
35
#include <utility>
36
37
using namespace std;
38
using namespace solidity;
39
using namespace solidity::frontend;
40
41
ASTNode::ASTNode(int64_t _id, SourceLocation _location):
42
  m_id(static_cast<size_t>(_id)),
43
  m_location(std::move(_location))
44
0
{
45
0
}
46
47
Declaration const* ASTNode::referencedDeclaration(Expression const& _expression)
48
0
{
49
0
  if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_expression))
50
0
    return memberAccess->annotation().referencedDeclaration;
51
0
  else if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(&_expression))
52
0
    return identifierPath->annotation().referencedDeclaration;
53
0
  else if (auto const* identifier = dynamic_cast<Identifier const*>(&_expression))
54
0
    return identifier->annotation().referencedDeclaration;
55
0
  else
56
0
    return nullptr;
57
0
}
58
59
FunctionDefinition const* ASTNode::resolveFunctionCall(FunctionCall const& _functionCall, ContractDefinition const* _mostDerivedContract)
60
0
{
61
0
  auto const* functionDef = dynamic_cast<FunctionDefinition const*>(
62
0
    ASTNode::referencedDeclaration(_functionCall.expression())
63
0
  );
64
65
0
  if (!functionDef)
66
0
    return nullptr;
67
68
0
  if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_functionCall.expression()))
69
0
  {
70
0
    if (*memberAccess->annotation().requiredLookup == VirtualLookup::Super)
71
0
    {
72
0
      if (auto const typeType = dynamic_cast<TypeType const*>(memberAccess->expression().annotation().type))
73
0
        if (auto const contractType = dynamic_cast<ContractType const*>(typeType->actualType()))
74
0
        {
75
0
          solAssert(_mostDerivedContract, "");
76
0
          solAssert(contractType->isSuper(), "");
77
0
          ContractDefinition const* superContract = contractType->contractDefinition().superContract(*_mostDerivedContract);
78
79
0
          return &functionDef->resolveVirtual(
80
0
            *_mostDerivedContract,
81
0
            superContract
82
0
          );
83
0
        }
84
0
    }
85
0
    else
86
0
      solAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Static, "");
87
0
  }
88
0
  else if (auto const* identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
89
0
  {
90
0
    solAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, "");
91
0
    if (functionDef->virtualSemantics())
92
0
    {
93
0
      solAssert(_mostDerivedContract, "");
94
0
      return &functionDef->resolveVirtual(*_mostDerivedContract);
95
0
    }
96
0
  }
97
0
  else
98
0
    solAssert(false, "");
99
100
0
  return functionDef;
101
0
}
102
103
ASTAnnotation& ASTNode::annotation() const
104
0
{
105
0
  if (!m_annotation)
106
0
    m_annotation = make_unique<ASTAnnotation>();
107
0
  return *m_annotation;
108
0
}
109
110
SourceUnitAnnotation& SourceUnit::annotation() const
111
0
{
112
0
  return initAnnotation<SourceUnitAnnotation>();
113
0
}
114
115
set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, set<SourceUnit const*> _skipList) const
116
0
{
117
0
  set<SourceUnit const*> sourceUnits;
118
0
  for (ImportDirective const* importDirective: filteredNodes<ImportDirective>(nodes()))
119
0
  {
120
0
    auto const& sourceUnit = importDirective->annotation().sourceUnit;
121
0
    if (!_skipList.count(sourceUnit))
122
0
    {
123
0
      _skipList.insert(sourceUnit);
124
0
      sourceUnits.insert(sourceUnit);
125
0
      if (_recurse)
126
0
        sourceUnits += sourceUnit->referencedSourceUnits(true, _skipList);
127
0
    }
128
0
  }
129
0
  return sourceUnits;
130
0
}
131
132
ImportAnnotation& ImportDirective::annotation() const
133
0
{
134
0
  return initAnnotation<ImportAnnotation>();
135
0
}
136
137
Type const* ImportDirective::type() const
138
0
{
139
0
  solAssert(!!annotation().sourceUnit, "");
140
0
  return TypeProvider::module(*annotation().sourceUnit);
141
0
}
142
143
bool ContractDefinition::derivesFrom(ContractDefinition const& _base) const
144
0
{
145
0
  return util::contains(annotation().linearizedBaseContracts, &_base);
146
0
}
147
148
map<util::FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const
149
0
{
150
0
  auto exportedFunctionList = interfaceFunctionList(_includeInheritedFunctions);
151
152
0
  map<util::FixedHash<4>, FunctionTypePointer> exportedFunctions;
153
0
  for (auto const& it: exportedFunctionList)
154
0
    exportedFunctions.insert(it);
155
156
0
  solAssert(
157
0
    exportedFunctionList.size() == exportedFunctions.size(),
158
0
    "Hash collision at Function Definition Hash calculation"
159
0
  );
160
161
0
  return exportedFunctions;
162
0
}
163
164
FunctionDefinition const* ContractDefinition::constructor() const
165
0
{
166
0
  for (FunctionDefinition const* f: definedFunctions())
167
0
    if (f->isConstructor())
168
0
      return f;
169
0
  return nullptr;
170
0
}
171
172
bool ContractDefinition::canBeDeployed() const
173
0
{
174
0
  return !abstract() && !isInterface();
175
0
}
176
177
FunctionDefinition const* ContractDefinition::fallbackFunction() const
178
0
{
179
0
  for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
180
0
    for (FunctionDefinition const* f: contract->definedFunctions())
181
0
      if (f->isFallback())
182
0
        return f;
183
0
  return nullptr;
184
0
}
185
186
FunctionDefinition const* ContractDefinition::receiveFunction() const
187
0
{
188
0
  for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
189
0
    for (FunctionDefinition const* f: contract->definedFunctions())
190
0
      if (f->isReceive())
191
0
        return f;
192
0
  return nullptr;
193
0
}
194
195
vector<EventDefinition const*> const& ContractDefinition::definedInterfaceEvents() const
196
0
{
197
0
  return m_interfaceEvents.init([&]{
198
0
    set<string> eventsSeen;
199
0
    vector<EventDefinition const*> interfaceEvents;
200
201
0
    for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
202
0
      for (EventDefinition const* e: contract->events())
203
0
      {
204
        /// NOTE: this requires the "internal" version of an Event,
205
        ///       though here internal strictly refers to visibility,
206
        ///       and not to function encoding (jump vs. call)
207
0
        auto const& function = e->functionType(true);
208
0
        solAssert(function, "");
209
0
        string eventSignature = function->externalSignature();
210
0
        if (eventsSeen.count(eventSignature) == 0)
211
0
        {
212
0
          eventsSeen.insert(eventSignature);
213
0
          interfaceEvents.push_back(e);
214
0
        }
215
0
      }
216
0
    return interfaceEvents;
217
0
  });
218
0
}
219
220
vector<EventDefinition const*> const ContractDefinition::usedInterfaceEvents() const
221
0
{
222
0
  solAssert(annotation().creationCallGraph.set(), "");
223
224
0
  return util::convertContainer<std::vector<EventDefinition const*>>(
225
0
    (*annotation().creationCallGraph)->emittedEvents +
226
0
    (*annotation().deployedCallGraph)->emittedEvents
227
0
  );
228
0
}
229
230
vector<ErrorDefinition const*> ContractDefinition::interfaceErrors(bool _requireCallGraph) const
231
0
{
232
0
  set<ErrorDefinition const*, CompareByID> result;
233
0
  for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
234
0
    result += filteredNodes<ErrorDefinition>(contract->m_subNodes);
235
0
  solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set(), "");
236
0
  if (_requireCallGraph)
237
0
    solAssert(annotation().creationCallGraph.set(), "");
238
0
  if (annotation().creationCallGraph.set())
239
0
    result +=
240
0
      (*annotation().creationCallGraph)->usedErrors +
241
0
      (*annotation().deployedCallGraph)->usedErrors;
242
0
  return util::convertContainer<vector<ErrorDefinition const*>>(move(result));
243
0
}
244
245
vector<pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const
246
0
{
247
0
  return m_interfaceFunctionList[_includeInheritedFunctions].init([&]{
248
0
    set<string> signaturesSeen;
249
0
    vector<pair<util::FixedHash<4>, FunctionTypePointer>> interfaceFunctionList;
250
251
0
    for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
252
0
    {
253
0
      if (_includeInheritedFunctions == false && contract != this)
254
0
        continue;
255
0
      vector<FunctionTypePointer> functions;
256
0
      for (FunctionDefinition const* f: contract->definedFunctions())
257
0
        if (f->isPartOfExternalInterface())
258
0
          functions.push_back(TypeProvider::function(*f, FunctionType::Kind::External));
259
0
      for (VariableDeclaration const* v: contract->stateVariables())
260
0
        if (v->isPartOfExternalInterface())
261
0
          functions.push_back(TypeProvider::function(*v));
262
0
      for (FunctionTypePointer const& fun: functions)
263
0
      {
264
0
        if (!fun->interfaceFunctionType())
265
          // Fails hopefully because we already registered the error
266
0
          continue;
267
0
        string functionSignature = fun->externalSignature();
268
0
        if (signaturesSeen.count(functionSignature) == 0)
269
0
        {
270
0
          signaturesSeen.insert(functionSignature);
271
0
          util::FixedHash<4> hash(util::keccak256(functionSignature));
272
0
          interfaceFunctionList.emplace_back(hash, fun);
273
0
        }
274
0
      }
275
0
    }
276
277
0
    return interfaceFunctionList;
278
0
  });
279
0
}
280
281
uint32_t ContractDefinition::interfaceId() const
282
0
{
283
0
  uint32_t result{0};
284
0
  for (auto const& function: interfaceFunctionList(false))
285
0
    result ^= fromBigEndian<uint32_t>(function.first.ref());
286
0
  return result;
287
0
}
288
289
Type const* ContractDefinition::type() const
290
0
{
291
0
  return TypeProvider::typeType(TypeProvider::contract(*this));
292
0
}
293
294
ContractDefinitionAnnotation& ContractDefinition::annotation() const
295
0
{
296
0
  return initAnnotation<ContractDefinitionAnnotation>();
297
0
}
298
299
ContractDefinition const* ContractDefinition::superContract(ContractDefinition const& _mostDerivedContract) const
300
0
{
301
0
  auto const& hierarchy = _mostDerivedContract.annotation().linearizedBaseContracts;
302
0
  auto it = find(hierarchy.begin(), hierarchy.end(), this);
303
0
  solAssert(it != hierarchy.end(), "Base not found in inheritance hierarchy.");
304
0
  ++it;
305
0
  if (it == hierarchy.end())
306
0
    return nullptr;
307
0
  else
308
0
  {
309
0
    solAssert(*it != this, "");
310
0
    return *it;
311
0
  }
312
0
}
313
314
FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition const& _mostDerivedContract) const
315
0
{
316
0
  ContractDefinition const* next = superContract(_mostDerivedContract);
317
0
  if (next == nullptr)
318
0
    return nullptr;
319
0
  for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
320
0
    if (c == next || next == nullptr)
321
0
    {
322
0
      if (c->constructor())
323
0
        return c->constructor();
324
0
      next = nullptr;
325
0
    }
326
327
0
  return nullptr;
328
0
}
329
330
multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const
331
0
{
332
0
  return m_definedFunctionsByName.init([&]{
333
0
    std::multimap<std::string, FunctionDefinition const*> result;
334
0
    for (FunctionDefinition const* fun: filteredNodes<FunctionDefinition>(m_subNodes))
335
0
      result.insert({fun->name(), fun});
336
0
    return result;
337
0
  });
338
0
}
339
340
341
TypeNameAnnotation& TypeName::annotation() const
342
0
{
343
0
  return initAnnotation<TypeNameAnnotation>();
344
0
}
345
346
Type const* UserDefinedValueTypeDefinition::type() const
347
0
{
348
0
  solAssert(m_underlyingType->annotation().type, "");
349
0
  return TypeProvider::typeType(TypeProvider::userDefinedValueType(*this));
350
0
}
351
352
TypeDeclarationAnnotation& UserDefinedValueTypeDefinition::annotation() const
353
0
{
354
0
  return initAnnotation<TypeDeclarationAnnotation>();
355
0
}
356
357
Type const* StructDefinition::type() const
358
0
{
359
0
  solAssert(annotation().recursive.has_value(), "Requested struct type before DeclarationTypeChecker.");
360
0
  return TypeProvider::typeType(TypeProvider::structType(*this, DataLocation::Storage));
361
0
}
362
363
StructDeclarationAnnotation& StructDefinition::annotation() const
364
0
{
365
0
  return initAnnotation<StructDeclarationAnnotation>();
366
0
}
367
368
Type const* EnumValue::type() const
369
0
{
370
0
  auto parentDef = dynamic_cast<EnumDefinition const*>(scope());
371
0
  solAssert(parentDef, "Enclosing Scope of EnumValue was not set");
372
0
  return TypeProvider::enumType(*parentDef);
373
0
}
374
375
Type const* EnumDefinition::type() const
376
0
{
377
0
  return TypeProvider::typeType(TypeProvider::enumType(*this));
378
0
}
379
380
TypeDeclarationAnnotation& EnumDefinition::annotation() const
381
0
{
382
0
  return initAnnotation<TypeDeclarationAnnotation>();
383
0
}
384
385
bool FunctionDefinition::libraryFunction() const
386
0
{
387
0
  if (auto const* contractDef = dynamic_cast<ContractDefinition const*>(scope()))
388
0
    return contractDef->isLibrary();
389
0
  return false;
390
0
}
391
392
Visibility FunctionDefinition::defaultVisibility() const
393
0
{
394
0
  solAssert(!isConstructor(), "");
395
0
  return isFree() ? Visibility::Internal : Declaration::defaultVisibility();
396
0
}
397
398
FunctionTypePointer FunctionDefinition::functionType(bool _internal) const
399
0
{
400
0
  if (_internal)
401
0
  {
402
0
    switch (visibility())
403
0
    {
404
0
    case Visibility::Default:
405
0
      solAssert(false, "visibility() should not return Default");
406
0
    case Visibility::Private:
407
0
    case Visibility::Internal:
408
0
    case Visibility::Public:
409
0
      return TypeProvider::function(*this, FunctionType::Kind::Internal);
410
0
    case Visibility::External:
411
0
      return {};
412
0
    }
413
0
  }
414
0
  else
415
0
  {
416
0
    switch (visibility())
417
0
    {
418
0
    case Visibility::Default:
419
0
      solAssert(false, "visibility() should not return Default");
420
0
    case Visibility::Private:
421
0
    case Visibility::Internal:
422
0
      return {};
423
0
    case Visibility::Public:
424
0
    case Visibility::External:
425
0
      return TypeProvider::function(*this, FunctionType::Kind::External);
426
0
    }
427
0
  }
428
429
  // To make the compiler happy
430
0
  return {};
431
0
}
432
433
Type const* FunctionDefinition::type() const
434
0
{
435
0
  solAssert(visibility() != Visibility::External, "");
436
0
  return TypeProvider::function(*this, FunctionType::Kind::Internal);
437
0
}
438
439
Type const* FunctionDefinition::typeViaContractName() const
440
0
{
441
0
  if (libraryFunction())
442
0
  {
443
0
    if (isPublic())
444
0
      return FunctionType(*this).asExternallyCallableFunction(true);
445
0
    else
446
0
      return TypeProvider::function(*this, FunctionType::Kind::Internal);
447
0
  }
448
0
  else
449
0
    return TypeProvider::function(*this, FunctionType::Kind::Declaration);
450
0
}
451
452
string FunctionDefinition::externalSignature() const
453
0
{
454
0
  return TypeProvider::function(*this)->externalSignature();
455
0
}
456
457
string FunctionDefinition::externalIdentifierHex() const
458
0
{
459
0
  return TypeProvider::function(*this)->externalIdentifierHex();
460
0
}
461
462
FunctionDefinitionAnnotation& FunctionDefinition::annotation() const
463
0
{
464
0
  return initAnnotation<FunctionDefinitionAnnotation>();
465
0
}
466
467
FunctionDefinition const& FunctionDefinition::resolveVirtual(
468
  ContractDefinition const& _mostDerivedContract,
469
  ContractDefinition const* _searchStart
470
) const
471
0
{
472
0
  solAssert(!isConstructor(), "");
473
0
  solAssert(!name().empty(), "");
474
475
  // If we are not doing super-lookup and the function is not virtual, we can stop here.
476
0
  if (_searchStart == nullptr && !virtualSemantics())
477
0
    return *this;
478
479
0
  solAssert(!isFree(), "");
480
0
  solAssert(isOrdinary(), "");
481
0
  solAssert(!libraryFunction(), "");
482
483
  // We actually do not want the externally callable function here.
484
  // This is just to add an assertion since the comparison used to be less strict.
485
0
  FunctionType const* externalFunctionType = TypeProvider::function(*this)->asExternallyCallableFunction(false);
486
487
0
  bool foundSearchStart = (_searchStart == nullptr);
488
0
  for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
489
0
  {
490
0
    if (!foundSearchStart && c != _searchStart)
491
0
      continue;
492
0
    else
493
0
      foundSearchStart = true;
494
495
0
    for (FunctionDefinition const* function: c->definedFunctions(name()))
496
0
      if (
497
        // With super lookup analysis guarantees that there is an implemented function in the chain.
498
        // With virtual lookup there are valid cases where returning an unimplemented one is fine.
499
0
        (function->isImplemented() || _searchStart == nullptr) &&
500
0
        FunctionType(*function).asExternallyCallableFunction(false)->hasEqualParameterTypes(*externalFunctionType)
501
0
      )
502
0
      {
503
0
        solAssert(FunctionType(*function).hasEqualParameterTypes(*TypeProvider::function(*this)));
504
0
        return *function;
505
0
      }
506
0
  }
507
508
0
  solAssert(false, "Virtual function " + name() + " not found.");
509
0
  return *this; // not reached
510
0
}
511
512
Type const* ModifierDefinition::type() const
513
0
{
514
0
  return TypeProvider::modifier(*this);
515
0
}
516
517
ModifierDefinitionAnnotation& ModifierDefinition::annotation() const
518
0
{
519
0
  return initAnnotation<ModifierDefinitionAnnotation>();
520
0
}
521
522
ModifierDefinition const& ModifierDefinition::resolveVirtual(
523
  ContractDefinition const& _mostDerivedContract,
524
  ContractDefinition const* _searchStart
525
) const
526
0
{
527
  // Super is not possible with modifiers
528
0
  solAssert(_searchStart == nullptr, "Used super in connection with modifiers.");
529
530
  // The modifier is not virtual, we can stop here.
531
0
  if (!virtualSemantics())
532
0
    return *this;
533
534
0
  solAssert(!dynamic_cast<ContractDefinition const&>(*scope()).isLibrary(), "");
535
536
0
  for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
537
0
    for (ModifierDefinition const* modifier: c->functionModifiers())
538
0
      if (modifier->name() == name())
539
0
        return *modifier;
540
541
0
  solAssert(false, "Virtual modifier " + name() + " not found.");
542
0
  return *this; // not reached
543
0
}
544
545
546
Type const* EventDefinition::type() const
547
0
{
548
0
  return TypeProvider::function(*this);
549
0
}
550
551
FunctionTypePointer EventDefinition::functionType(bool _internal) const
552
0
{
553
0
  if (_internal)
554
0
    return TypeProvider::function(*this);
555
0
  else
556
0
    return nullptr;
557
0
}
558
559
EventDefinitionAnnotation& EventDefinition::annotation() const
560
0
{
561
0
  return initAnnotation<EventDefinitionAnnotation>();
562
0
}
563
564
Type const* ErrorDefinition::type() const
565
0
{
566
0
  return TypeProvider::function(*this);
567
0
}
568
569
FunctionTypePointer ErrorDefinition::functionType(bool _internal) const
570
0
{
571
0
  if (_internal)
572
0
    return TypeProvider::function(*this);
573
0
  else
574
0
    return nullptr;
575
0
}
576
577
ErrorDefinitionAnnotation& ErrorDefinition::annotation() const
578
0
{
579
0
  return initAnnotation<ErrorDefinitionAnnotation>();
580
0
}
581
582
SourceUnit const& Scopable::sourceUnit() const
583
0
{
584
0
  ASTNode const* s = scope();
585
0
  solAssert(s, "");
586
  // will not always be a declaration
587
0
  while (dynamic_cast<Scopable const*>(s) && dynamic_cast<Scopable const*>(s)->scope())
588
0
    s = dynamic_cast<Scopable const*>(s)->scope();
589
0
  return dynamic_cast<SourceUnit const&>(*s);
590
0
}
591
592
CallableDeclaration const* Scopable::functionOrModifierDefinition() const
593
0
{
594
0
  ASTNode const* s = scope();
595
0
  solAssert(s, "");
596
0
  while (dynamic_cast<Scopable const*>(s))
597
0
  {
598
0
    if (auto funDef = dynamic_cast<FunctionDefinition const*>(s))
599
0
      return funDef;
600
0
    if (auto modDef = dynamic_cast<ModifierDefinition const*>(s))
601
0
      return modDef;
602
0
    s = dynamic_cast<Scopable const*>(s)->scope();
603
0
  }
604
0
  return nullptr;
605
0
}
606
607
string Scopable::sourceUnitName() const
608
0
{
609
0
  return *sourceUnit().annotation().path;
610
0
}
611
612
bool Declaration::isEnumValue() const
613
0
{
614
0
  solAssert(scope(), "");
615
0
  return dynamic_cast<EnumDefinition const*>(scope());
616
0
}
617
618
bool Declaration::isStructMember() const
619
0
{
620
0
  solAssert(scope(), "");
621
0
  return dynamic_cast<StructDefinition const*>(scope());
622
0
}
623
624
bool Declaration::isEventOrErrorParameter() const
625
0
{
626
0
  solAssert(scope(), "");
627
0
  return dynamic_cast<EventDefinition const*>(scope()) || dynamic_cast<ErrorDefinition const*>(scope());
628
0
}
629
630
bool Declaration::isVisibleAsUnqualifiedName() const
631
0
{
632
0
  if (!scope())
633
0
    return true;
634
0
  if (isStructMember() || isEnumValue() || isEventOrErrorParameter())
635
0
    return false;
636
0
  if (auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(scope()))
637
0
    if (!functionDefinition->isImplemented())
638
0
      return false; // parameter of a function without body
639
0
  return true;
640
0
}
641
642
DeclarationAnnotation& Declaration::annotation() const
643
0
{
644
0
  return initAnnotation<DeclarationAnnotation>();
645
0
}
646
647
bool VariableDeclaration::isLValue() const
648
0
{
649
  // Constant declared variables are Read-Only
650
0
  return !isConstant();
651
0
}
652
653
bool VariableDeclaration::isLocalVariable() const
654
0
{
655
0
  auto s = scope();
656
0
  return
657
0
    dynamic_cast<FunctionTypeName const*>(s) ||
658
0
    dynamic_cast<CallableDeclaration const*>(s) ||
659
0
    dynamic_cast<Block const*>(s) ||
660
0
    dynamic_cast<TryCatchClause const*>(s) ||
661
0
    dynamic_cast<ForStatement const*>(s);
662
0
}
663
664
bool VariableDeclaration::isCallableOrCatchParameter() const
665
0
{
666
0
  if (isReturnParameter() || isTryCatchParameter())
667
0
    return true;
668
669
0
  vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
670
671
0
  if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
672
0
    parameters = &funTypeName->parameterTypes();
673
0
  else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
674
0
    parameters = &callable->parameters();
675
676
0
  if (parameters)
677
0
    for (auto const& variable: *parameters)
678
0
      if (variable.get() == this)
679
0
        return true;
680
0
  return false;
681
0
}
682
683
bool VariableDeclaration::isLocalOrReturn() const
684
0
{
685
0
  return isReturnParameter() || (isLocalVariable() && !isCallableOrCatchParameter());
686
0
}
687
688
bool VariableDeclaration::isReturnParameter() const
689
0
{
690
0
  vector<ASTPointer<VariableDeclaration>> const* returnParameters = nullptr;
691
692
0
  if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
693
0
    returnParameters = &funTypeName->returnParameterTypes();
694
0
  else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
695
0
    if (callable->returnParameterList())
696
0
      returnParameters = &callable->returnParameterList()->parameters();
697
698
0
  if (returnParameters)
699
0
    for (auto const& variable: *returnParameters)
700
0
      if (variable.get() == this)
701
0
        return true;
702
0
  return false;
703
0
}
704
705
bool VariableDeclaration::isTryCatchParameter() const
706
0
{
707
0
  return dynamic_cast<TryCatchClause const*>(scope());
708
0
}
709
710
bool VariableDeclaration::isExternalCallableParameter() const
711
0
{
712
0
  if (!isCallableOrCatchParameter())
713
0
    return false;
714
715
0
  if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
716
0
    if (callable->visibility() == Visibility::External)
717
0
      return !isReturnParameter();
718
719
0
  return false;
720
0
}
721
722
bool VariableDeclaration::isPublicCallableParameter() const
723
0
{
724
0
  if (!isCallableOrCatchParameter())
725
0
    return false;
726
727
0
  if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
728
0
    if (callable->visibility() == Visibility::Public)
729
0
      return !isReturnParameter();
730
731
0
  return false;
732
0
}
733
734
bool VariableDeclaration::isInternalCallableParameter() const
735
0
{
736
0
  if (!isCallableOrCatchParameter())
737
0
    return false;
738
739
0
  if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
740
0
    return funTypeName->visibility() == Visibility::Internal;
741
0
  else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
742
0
    return callable->visibility() <= Visibility::Internal;
743
0
  return false;
744
0
}
745
746
bool VariableDeclaration::isConstructorParameter() const
747
0
{
748
0
  if (!isCallableOrCatchParameter())
749
0
    return false;
750
0
  if (auto const* function = dynamic_cast<FunctionDefinition const*>(scope()))
751
0
    return function->isConstructor();
752
0
  return false;
753
0
}
754
755
bool VariableDeclaration::isLibraryFunctionParameter() const
756
0
{
757
0
  if (!isCallableOrCatchParameter())
758
0
    return false;
759
0
  if (auto const* funDef = dynamic_cast<FunctionDefinition const*>(scope()))
760
0
    return funDef->libraryFunction();
761
0
  return false;
762
0
}
763
764
bool VariableDeclaration::hasReferenceOrMappingType() const
765
0
{
766
0
  solAssert(typeName().annotation().type, "Can only be called after reference resolution");
767
0
  Type const* type = typeName().annotation().type;
768
0
  return type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type);
769
0
}
770
771
bool VariableDeclaration::isStateVariable() const
772
0
{
773
0
  return dynamic_cast<ContractDefinition const*>(scope());
774
0
}
775
776
bool VariableDeclaration::isFileLevelVariable() const
777
0
{
778
0
  return dynamic_cast<SourceUnit const*>(scope());
779
0
}
780
781
set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const
782
0
{
783
0
  using Location = VariableDeclaration::Location;
784
785
0
  if (!hasReferenceOrMappingType() || isStateVariable() || isEventOrErrorParameter())
786
0
    return set<Location>{ Location::Unspecified };
787
0
  else if (isCallableOrCatchParameter())
788
0
  {
789
0
    set<Location> locations{ Location::Memory };
790
0
    if (
791
0
      isConstructorParameter() ||
792
0
      isInternalCallableParameter() ||
793
0
      isLibraryFunctionParameter()
794
0
    )
795
0
      locations.insert(Location::Storage);
796
0
    if (!isTryCatchParameter() && !isConstructorParameter())
797
0
      locations.insert(Location::CallData);
798
799
0
    return locations;
800
0
  }
801
0
  else if (isLocalVariable())
802
    // Further restrictions will be imposed later on.
803
0
    return set<Location>{ Location::Memory, Location::Storage, Location::CallData };
804
0
  else
805
    // Struct members etc.
806
0
    return set<Location>{ Location::Unspecified };
807
0
}
808
809
string VariableDeclaration::externalIdentifierHex() const
810
0
{
811
0
  solAssert(isStateVariable() && isPublic(), "Can only be called for public state variables");
812
0
  return TypeProvider::function(*this)->externalIdentifierHex();
813
0
}
814
815
Type const* VariableDeclaration::type() const
816
0
{
817
0
  return annotation().type;
818
0
}
819
820
FunctionTypePointer VariableDeclaration::functionType(bool _internal) const
821
0
{
822
0
  if (_internal)
823
0
    return nullptr;
824
0
  switch (visibility())
825
0
  {
826
0
  case Visibility::Default:
827
0
    solAssert(false, "visibility() should not return Default");
828
0
  case Visibility::Private:
829
0
  case Visibility::Internal:
830
0
    return nullptr;
831
0
  case Visibility::Public:
832
0
  case Visibility::External:
833
0
    return TypeProvider::function(*this);
834
0
  }
835
836
  // To make the compiler happy
837
0
  return nullptr;
838
0
}
839
840
VariableDeclarationAnnotation& VariableDeclaration::annotation() const
841
0
{
842
0
  return initAnnotation<VariableDeclarationAnnotation>();
843
0
}
844
845
StatementAnnotation& Statement::annotation() const
846
0
{
847
0
  return initAnnotation<StatementAnnotation>();
848
0
}
849
850
InlineAssemblyAnnotation& InlineAssembly::annotation() const
851
0
{
852
0
  return initAnnotation<InlineAssemblyAnnotation>();
853
0
}
854
855
BlockAnnotation& Block::annotation() const
856
0
{
857
0
  return initAnnotation<BlockAnnotation>();
858
0
}
859
860
TryCatchClauseAnnotation& TryCatchClause::annotation() const
861
0
{
862
0
  return initAnnotation<TryCatchClauseAnnotation>();
863
0
}
864
865
ForStatementAnnotation& ForStatement::annotation() const
866
0
{
867
0
  return initAnnotation<ForStatementAnnotation>();
868
0
}
869
870
ReturnAnnotation& Return::annotation() const
871
0
{
872
0
  return initAnnotation<ReturnAnnotation>();
873
0
}
874
875
ExpressionAnnotation& Expression::annotation() const
876
0
{
877
0
  return initAnnotation<ExpressionAnnotation>();
878
0
}
879
880
MemberAccessAnnotation& MemberAccess::annotation() const
881
0
{
882
0
  return initAnnotation<MemberAccessAnnotation>();
883
0
}
884
885
BinaryOperationAnnotation& BinaryOperation::annotation() const
886
0
{
887
0
  return initAnnotation<BinaryOperationAnnotation>();
888
0
}
889
890
FunctionCallAnnotation& FunctionCall::annotation() const
891
0
{
892
0
  return initAnnotation<FunctionCallAnnotation>();
893
0
}
894
895
vector<ASTPointer<Expression const>> FunctionCall::sortedArguments() const
896
0
{
897
  // normal arguments
898
0
  if (m_names.empty())
899
0
    return arguments();
900
901
  // named arguments
902
0
  FunctionTypePointer functionType;
903
0
  if (*annotation().kind == FunctionCallKind::StructConstructorCall)
904
0
  {
905
0
    auto const& type = dynamic_cast<TypeType const&>(*m_expression->annotation().type);
906
0
    auto const& structType = dynamic_cast<StructType const&>(*type.actualType());
907
0
    functionType = structType.constructorType();
908
0
  }
909
0
  else
910
0
    functionType = dynamic_cast<FunctionType const*>(m_expression->annotation().type);
911
912
0
  vector<ASTPointer<Expression const>> sorted;
913
0
  for (auto const& parameterName: functionType->parameterNames())
914
0
  {
915
0
    bool found = false;
916
0
    for (size_t j = 0; j < m_names.size() && !found; j++)
917
0
      if ((found = (parameterName == *m_names.at(j))))
918
        // we found the actual parameter position
919
0
        sorted.push_back(m_arguments.at(j));
920
0
    solAssert(found, "");
921
0
  }
922
923
0
  if (!functionType->takesArbitraryParameters())
924
0
  {
925
0
    solAssert(m_arguments.size() == functionType->parameterTypes().size(), "");
926
0
    solAssert(m_arguments.size() == m_names.size(), "");
927
0
    solAssert(m_arguments.size() == sorted.size(), "");
928
0
  }
929
930
0
  return sorted;
931
0
}
932
933
IdentifierAnnotation& Identifier::annotation() const
934
0
{
935
0
  return initAnnotation<IdentifierAnnotation>();
936
0
}
937
938
ASTString Literal::valueWithoutUnderscores() const
939
0
{
940
0
  return boost::erase_all_copy(value(), "_");
941
0
}
942
943
bool Literal::isHexNumber() const
944
0
{
945
0
  if (token() != Token::Number)
946
0
    return false;
947
0
  return boost::starts_with(value(), "0x");
948
0
}
949
950
bool Literal::looksLikeAddress() const
951
0
{
952
0
  if (subDenomination() != SubDenomination::None)
953
0
    return false;
954
955
0
  if (!isHexNumber())
956
0
    return false;
957
958
0
  return abs(int(valueWithoutUnderscores().length()) - 42) <= 1;
959
0
}
960
961
bool Literal::passesAddressChecksum() const
962
0
{
963
0
  solAssert(isHexNumber(), "Expected hex number");
964
0
  return util::passesAddressChecksum(valueWithoutUnderscores(), true);
965
0
}
966
967
string Literal::getChecksummedAddress() const
968
0
{
969
0
  solAssert(isHexNumber(), "Expected hex number");
970
  /// Pad literal to be a proper hex address.
971
0
  string address = valueWithoutUnderscores().substr(2);
972
0
  if (address.length() > 40)
973
0
    return string();
974
0
  address.insert(address.begin(), 40 - address.size(), '0');
975
0
  return util::getChecksummedAddress(address);
976
0
}
977
978
TryCatchClause const* TryStatement::successClause() const
979
0
{
980
0
  solAssert(m_clauses.size() > 0, "");
981
0
  return m_clauses[0].get();
982
0
}
983
984
TryCatchClause const* TryStatement::panicClause() const
985
0
{
986
0
  for (size_t i = 1; i < m_clauses.size(); ++i)
987
0
    if (m_clauses[i]->errorName() == "Panic")
988
0
      return m_clauses[i].get();
989
0
  return nullptr;
990
0
}
991
992
TryCatchClause const* TryStatement::errorClause() const
993
0
{
994
0
  for (size_t i = 1; i < m_clauses.size(); ++i)
995
0
    if (m_clauses[i]->errorName() == "Error")
996
0
      return m_clauses[i].get();
997
0
  return nullptr;
998
0
}
999
1000
TryCatchClause const* TryStatement::fallbackClause() const
1001
0
{
1002
0
  for (size_t i = 1; i < m_clauses.size(); ++i)
1003
0
    if (m_clauses[i]->errorName().empty())
1004
0
      return m_clauses[i].get();
1005
0
  return nullptr;
1006
0
}